2

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.

2

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
2

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) {
        fprintf(stderr, "Error or file not found: %s\n", argv[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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .