How to investigate fragmentation of one file?

I'd like to see if one of my file is "all over the place", ie fragmented in little pieces at different locations on my hard drive.

I'm not looking for a software like iDefrag but rather a command line utility. I know nothing of file systems, nodes, etc. Does such a CL tool exist? More generally, how do you know where files physically are?

The file I want to investigate is ~/Library/Application Support/Google/Chrome/Default/History indexes, but that's more of a general question.

-

HFSDebug was a decent tool on older version of OSX, however I do not beleive it is Lion compliant.

http://www.osxbook.com/software/hfsdebug/

The original maker of HFSDebug recommends File Xray, a commercial program to do the same tasks and more - check it out here

http://filexray.com/

-
Thanks! However I must say I really was more looking for a free tool. I'm positive there are CL tools to investigate the file system –  Arthur Jan 18 '12 at 19:33

I asked the same question on quora and someone impressively answered with a C program he made up himself.

Here is his code:

/*
check-frag filename [blockjump]
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <stdint.h>

int main(int argc, char *argv[]) {
struct log2phys lf;
int start, end, i, status;
int blockjump = 4096;
struct stat st_buf;

if (argc < 2) {
printf("Enter a filename.\n");
return 1;
}
if (argc == 3) {
blockjump = atoi(argv[2]);
}
printf("Using block size of %d\n", blockjump);
status = stat(argv[1], &st_buf);
if (status != 0 || (!(S_ISREG (st_buf.st_mode)))) {
fprintf(stderr, "Error reading file %s or file is not regular file.\n", argv[1]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
if (fd == -1) {
return 1;
}
start = lseek(fd, 0, SEEK_CUR);
end = lseek(fd, 0, SEEK_END);
printf("start: %d\tend: %d\n", start, end);
off_t last = 0;
int cblocks = 1;
int tblocks = 1;
for (i = 0; i < (end-blockjump); i=i+blockjump) {
tblocks++;
lseek(fd, i, SEEK_SET);
fcntl(fd, F_LOG2PHYS, &lf);
if (last != lf.l2p_devoffset && last != (lf.l2p_devoffset-blockjump)) {
printf("%jd\n", (intmax_t)lf.l2p_devoffset);
} else {
cblocks++;
}
last = lf.l2p_devoffset;

}
printf("contiguous blocks: %d\n", cblocks);
printf("total blocks: %d\n", tblocks);
printf("difference (fragmented extents): %d\n", tblocks-cblocks);
printf("percent contiguous in file: %f\n", (float)cblocks/(float)tblocks);
close(fd);

return 0;
}


Put that in a file, name it frag.c or something like that, and run make frag or gcc frag.c -o frag. Now you can run ./frag path/to/your/file. You can also add the block size as a second argument. Note that you'll have to be able to compile the program, which on Mac OS X is usually done by having XCode installed.

-