How to get free bytes and total bytes for volumes

  • I am trying to read the free bytes for a volume before trying to copy
    some files to it. Shouldn't be a big problem (even to a newbie - as i am
    one)
    but NSFileManager does not provide methods that do the job. Googling a bit
    i found out that i have to use some Carbon file manager functions. BUT
    that does not give me correct values (i think). When using this code:

    - (unsigned long long) getVolumeTotalBytesForPath: (NSString *) path
    {
        [path retain];
        SInt16 vRefNum = [self _getVolumeNumberForPath: path];
        unsigned long long returnValue = 0;
        OSErr osErr;

        FSVolumeInfo info;
        osErr = FSGetVolumeInfo (vRefNum, 0, NULL, kFSVolInfoSizes, &info,
    NULL, NULL);

        if (osErr == noErr) {
            returnValue = info.totalBytes;
        } else {
            NSLog(@"Could not retrive total byte size. Error: %i", osErr);
            returnValue = 0;
        }

        [path release];
        return returnValue;
    }

    - (unsigned long long) getVolumeFreeBytesForPath: (NSString *) path
    {
        [path retain];
        SInt16 vRefNum = [self _getVolumeNumberForPath: path];
        unsigned long long returnValue = 0;
        OSErr osErr;

        FSVolumeInfo info;
        osErr = FSGetVolumeInfo (vRefNum, 0, NULL, kFSVolInfoSizes, &info,
    NULL, NULL);

        if (osErr == noErr) {
            returnValue = info.freeBytes;
        } else {
            NSLog(@"Could not retrive free bytes. Error: %i", osErr);
            returnValue = 0;
        }

        [path release];
        return returnValue;
    }

    - (SInt16) _getVolumeNumberForPath: (NSString *) path
    {
        [path retain];

        FSRef pathRef;

        // why do i have to cast the fileSystemRepresentation to UInt8* anyway?
        // according to a thread from 2003 this should not be necessary
        FSPathMakeRef((UInt8*)[path fileSystemRepresentation], &pathRef, NULL);

        OSErr osErr;

        FSCatalogInfo catInfo;
        osErr = FSGetCatalogInfo(&pathRef, kFSCatInfoVolume, &catInfo, NULL,
    NULL, NULL);

        SInt16 returnValue = 0;

        if(osErr == noErr) {
            returnValue = catInfo.volume;
        }

        [path release];
        return returnValue;
    }

    [...]

    NSLog(@"Total volume size: %i bytes", [self getVolumeTotalBytesForPath:
    @"/Users/marc/Desktop"]);
    NSLog(@"Free volume size: %i bytes", [self getVolumeFreeBytesForPath:
    @"/Users/marc/Desktop"]);

    i get something like 3 free bytes and 18 total bytes using a path
    on my PowerBook's harddrive which has 80GB total and 12GB free
    space. In the documentation for FSVolumeInfo it says :

    [...]
    UInt64 totalBytes;
    UInt64 freeBytes;
    [...]

    so using an unsigned long long as the returnValue should be fine.
    i realized, though,  that the relation of free bytes to total bytes
    actually more or less fits: 12 GB is roughly 1/6 of 80GB and the same is
    true for 3 and 18. I am lost and i fear that i am probably making some
    stupid mistake...
  • > NSLog(@"Total volume size: %i bytes", [self
    > getVolumeTotalBytesForPath: @"/Users/marc/Desktop"]);
    > NSLog(@"Free volume size: %i bytes", [self
    > getVolumeFreeBytesForPath: @"/Users/marc/Desktop"]);
    >
    >
    > i get something like 3 free bytes and 18 total bytes using a path
    > on my PowerBook's harddrive which has 80GB total and 12GB free
    > space. In the documentation for FSVolumeInfo it says :

    using an 'unsigned long long' is fine but to log an 'unsigned long
    long' you have to use %llu and not %i

    like this:
    NSLog(@"Total volume size: %llu bytes", [self
    getVolumeTotalBytesForPath: @"/Users/marc/Desktop"]);
    NSLog(@"Free volume size: %llu bytes", [self
    getVolumeFreeBytesForPath: @"/Users/marc/Desktop"]);
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today