How do you find how much disk space is left in Cocoa?
I suppose I'd like to be able to find out for any storage, not just the system disk, but th开发者_JS百科at's most important.
Use -[NSFileManager attributesOfFileSystemForPath:error:]
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));
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;
}
Hard disk device manufacturers, use:
1GB = 1000MB
1MB = 1000 KB etc.
If you see a 8GB USB stick in Windows always shows less space than real (like 7,8 GB) because it is considered 1 GB = 1024 MB). In OSX the same USB stick is 8GB (real).
so (freeSpace / 1073741824)
must be (freeSpace / 1000000000)
at least in OSX
Through swift you can get free space by using this function
func getFreeSpace() -> CGFloat {
do {
let fileAttributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath("/")
if let size = fileAttributes[NSFileSystemFreeSize] as? CGFloat {
return size
}
} catch { }
return 0
}
Get from this post:
- (uint64_t)freeDiskspace
{
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
__autoreleasing NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
NSLog(@"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
} else {
NSLog(@"Error Obtaining System Memory Info: Domain = %@, Code = %d", [error domain], [error code]);
}
return totalFreeSpace;
}
The main difference is that you should use NSSearchPathForDirectioriesInDomains, otherwise I was getting correct value on simulator, but on the device '/' folder reference returns me something like 190MB which was not right.
Swift 3.0-4.0 on MacOS
I've done this for macOS and haven't had an issue. The output is in bytes so you have to divide it by the 1024.
func getHD() -> String {
do {
let du = try FileManager.default.attributesOfFileSystem(forPath: "/")
if let size = du[FileAttributeKey.systemFreeSize] as? Int64 {
return (String(size / 1024 / 1024 / 1024) + "GB")
}
debugPrint(du)
}
catch {
debugPrint(error)
return "Check Failed"
}
return "Checking..."
}
The FileManager.default.attributesOfFileSystem(forPath: "/")
is just getting the various attributes available for the root directory's file system. One of those attributes happens to be the Free Disk Space.
du[FileAttributeKey.systemFreeSize] as? Int64
You access that key (key:value) and typecast it to an Int to get your free disk space.
精彩评论