views:

478

answers:

3

I suppose I'd like to be able to find out for any storage, not just the system disk, but that's most important.

+6  A: 

-[NSFileManager attributesOfFileSystemForPath:error:]

Azeem.Butt
-[NSFileManager attributesOfFileSystemForPath:error:] doesn't return a dict with the key NSFileSystemFreeSize in it.
zekel
Whoops, you were right. Looks like I tried that on the class, not the instance.
zekel
+2  A: 

EDIT fileSystemAttributesAtPath: is deprecated, use attributesOfFileSystemForPath:error: as NSD suggested. I made a mistake when I thought it didn't work.

// this works
NSError *error = nil;
NSDictionary *attr = [NSFM attributesOfFileSystemForPath:@"/" error:&error];
if (!error) {
    double bytesFree = [[attr objectForKey:NSFileSystemFreeSize] doubleValue];
}

I tried this, attributesOfItemAtPath:error but the dict returned didn't seem to have the NSFileSystemFreeNodes key.

NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSDictionary *attr = [fm attributesOfItemAtPath:@"/" error:&error];
if (!error) {
    NSLog(@"Attr: %@", attr);
}

2009-10-28 17:21:11.936 MyApp[33149:a0b] Attr: {
    NSFileCreationDate = "2009-08-28 15:37:03 -0400";
    NSFileExtensionHidden = 0;
    NSFileGroupOwnerAccountID = 80;
    NSFileGroupOwnerAccountName = admin;
    NSFileModificationDate = "2009-10-28 15:22:15 -0400";
    NSFileOwnerAccountID = 0;
    NSFileOwnerAccountName = root;
    NSFilePosixPermissions = 1021;
    NSFileReferenceCount = 40;
    NSFileSize = 1428;
    NSFileSystemFileNumber = 2;
    NSFileSystemNumber = 234881026;
    NSFileType = NSFileTypeDirectory;
}

After looking around a bit, it seems like fileSystemAttributesAtPath: is the method that returns it. Weird.

NSFileManager *fm = [NSFileManager defaultManager];
NSDictionary *attr = [fm fileSystemAttributesAtPath:@"/"]; 
NSLog(@"Attr: %@", attr);


2009-10-28 17:24:07.993 MyApp[33283:a0b] Attr: {
    NSFileSystemFreeNodes = 5027061;
    NSFileSystemFreeSize = 20590841856;
    NSFileSystemNodes = 69697534;
    NSFileSystemNumber = 234881026;
    NSFileSystemSize = 285481107456;
}
zekel
“… use attributesOfFileSystemForPath:error: instead.” That's what NSD suggested, and you told him it didn't work. Does it work now?
Peter Hosey
Yeah, it does. Looks like I made a mistake before.
zekel
Two critiques: `error:` parameters take a pointer to a pointer to an object, `NSError **`. Thus, the correct null pointer constant is not `nil` (which would be a pointer to an object, either `<class-name> *` or `id`), it's `NULL`. More importantly, don't suppress the error return—pass a pointer to a variable there, and report the error if (and only if) the attempt to retrieve attributes fails. Silent failure is bad.
Peter Hosey
You're right on both counts. Added better handling to example code to be more instructive.
zekel
+1  A: 

I use this:

NSDictionary* fileAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:@"/"
                                                                                   error:&error];
unsigned long long freeSpace = [[fileAttributes objectForKey:NSFileSystemFreeSize] longLongValue];
NSLog(@"free disk space: %dGB", (int)(freeSpace / 1073741824));
Avi Cohen