How to detect total available/free disk space on the iPhone/iPad device?

后端 未结 18 1761
别跟我提以往
别跟我提以往 2020-11-22 11:14

I\'m looking for a better way to detect available/free disk space on the iPhone/iPad device programmatically.
Currently I\'m using the NSFileManager to detect the disk s

相关标签:
18条回答
  • 2020-11-22 11:40

    Swift 5 extension for FileManager with proper error handling and no automatic string conversions (convert byte count to string as you prefer). Also follows FileManager's naming.

    extension FileManager {
        func systemFreeSizeBytes() -> Result<Int64, Error> {
            do {
                let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
                guard let freeSize = attrs[.systemFreeSize] as? Int64 else {
                    return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system free size"]))
                }
                return .success(freeSize)
            } catch {
                return .failure(error)
            }
        }
    
        func systemSizeBytes() -> Result<Int64, Error> {
             do {
                 let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
                 guard let size = attrs[.systemSize] as? Int64 else {
                     return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system size"]))
                 }
                 return .success(size)
             } catch {
                 return .failure(error)
             }
         }
    }
    

    Example usage:

    let freeSizeResult = FileManager.default.systemFreeSizeBytes()
    switch freeSizeResult {
    case .failure(let error):
        print(error)
    case .success(let freeSize):
        let freeSizeString = ByteCountFormatter.string(fromByteCount: freeSize, countStyle: .file)
        print("free size: \(freeSizeString)")
    }
    
    0 讨论(0)
  • 2020-11-22 11:41

    Don't use 'unsigned', it is only 32 bits which will overflow past 4GB, which is less than the typical iPad/iPhone free space. Use unsigned long long (or uint64_t), and retrieve the value out of the NSNumber as a 64-bit int too using unsignedLongLongValue.

    0 讨论(0)
  • 2020-11-22 11:42

    for Swift as UIDevice extension

    extension UIDevice {
        func freeDiskspace() -> NSString {
            let failedResult: String = "Error Obtaining System Memory"
            guard let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last else {
                return failedResult
            }
            do {
                let dictionary = try NSFileManager.defaultManager().attributesOfFileSystemForPath(path)
                if let fileSystemSizeInBytes = dictionary[NSFileSystemSize] as? UInt,
                    let freeFileSystemSizeInBytes =     dictionary[NSFileSystemFreeSize] as? UInt {
                        return "Memory \(freeFileSystemSizeInBytes/1024/1024) of \(fileSystemSizeInBytes/1024/1024) Mb available."
                } else {
                        return failedResult
                }
            } catch {
                return failedResult
            }
        }
    }
    

    How to use:

    print("\(UIDevice.currentDevice().freeDiskspace())")
    

    Output will be:

    Memory 9656 of 207694 Mb available.
    
    0 讨论(0)
  • 2020-11-22 11:44

    ChrisJF answer in Swift 2.1 version:

    func freeSpaceInBytes() -> NSString{
    
        var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")
    
        do {
    
            let dictionary =  try NSFileManager.defaultManager().attributesOfFileSystemForPath(NSHomeDirectory())
            freeSpaceSize = (dictionary[NSFileSystemFreeSize]?.longLongValue)!
            remainingSpace = NSByteCountFormatter.stringFromByteCount(freeSpaceSize, countStyle: NSByteCountFormatterCountStyle.File)
    
        }
        catch let error as NSError {
    
            error.description
            NSLog(error.description)
    
        }
    
        return remainingSpace
    
    }
    
    0 讨论(0)
  • 2020-11-22 11:46

    If your looking to get the the remaining free space using Swift it is slightly different. You need to use attributesOfFileSystemForPath() instead of attributesOfItemAtPath():

    func deviceRemainingFreeSpaceInBytes() -> Int64? {
        let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        var attributes: [String: AnyObject]
        do {
            attributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last! as String)
            let freeSize = attributes[NSFileSystemFreeSize] as? NSNumber
            if (freeSize != nil) {
                return freeSize?.longLongValue
            } else {
                return nil
            }
        } catch {
            return nil
        }
    }
    

    Edit: Updated for Swift 1.0
    Edit 2: Updated for safety, using Martin R's answer.
    Edit 3: Updated for Swift 2.0 (by dgellow)

    0 讨论(0)
  • 2020-11-22 11:46

    For iOS >= 6.0 you can use the new NSByteCountFormatter. This code gets the number of free bytes remaining as a formatted string.

    NSError *error = nil;
    NSArray * const paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSDictionary * const pathAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths firstObject] error:&error];
    NSAssert(pathAttributes, @"");
    NSNumber * const fileSystemSizeInBytes = [pathAttributes objectForKey: NSFileSystemFreeSize];
    const long long numberOfBytesRemaining = [fileSystemSizeInBytes longLongValue];
    NSByteCountFormatter *byteCountFormatter = [[NSByteCountFormatter alloc] init];
    NSString *formattedNmberOfBytesRemaining = [byteCountFormatter stringFromByteCount:numberOfBytesRemaining];
    
    0 讨论(0)
提交回复
热议问题