1

以下是我用来在 iOS 设备上为我的应用获取可用存储空间的方法:

NSDictionary *dict = [[NSFileManager defaultManager] fileSystemAttributesAtPath:@"/var"];
NSNumber *freeSpace = [dict valueForKey:@"NSFileSystemFreeSize"];

但是,该值freeSpace与“设置”应用程序中显示的值不对应。该值始终大于设置显示的值。例如,freeSpace大约为 600,000,000 字节,其中“设置”显示为 357 MB。

为什么会这样?如何获得与设置显示的值相同的值?

4

4 回答 4

4

我在带有 iOS 6.1.4 的 iPhone5 上得到了相同的结果。

double freeSpaceMB = -1.;     
long long freeSpace =
            [[[[NSFileManager defaultManager]
            attributesOfFileSystemForPath:NSHomeDirectory()
                                    error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
        freeSpaceMB = (freeSpace * 1.)/ (1024 * 1024);   

X - 来自设置的值(使用)

我总是得到freeSpaceMB = X + 200。

我想这是iOS中的保留空间。但这只是猜测。

于 2013-11-12T02:02:16.507 回答
4

在 iOS 11 下,可以传递新的音量容量键,以URL.resourceValues(forKeys:)提供与设备设置中可用的值相匹配的值。

  • static let volumeAvailableCapacityKey: URLResourceKey 卷可用容量的密钥(以字节为单位)(只读)。

  • static let volumeAvailableCapacityForImportantUsageKey: URLResourceKey 用于存储重要资源的卷可用容量的密钥(以字节为单位)(只读)。

  • static let volumeAvailableCapacityForOpportunisticUsageKey: URLResourceKey 用于存储非必要资源的卷可用容量的密钥(以字节为单位)(只读)。

  • static let volumeTotalCapacityKey: URLResourceKey 卷总容量的键(以字节为单位)(只读)。

来自苹果的文档

概述

在您尝试在本地存储大量数据之前,请先确认您有足够的存储容量。要获取卷的存储容量,您需要构造一个 URL(使用 URL 的实例),该 URL 引用要查询的卷上的对象,然后查询该卷。

决定使用哪种查询类型

要使用的查询类型取决于存储的内容。如果您根据用户请求或应用程序正常运行所需的资源(例如,用户将要观看的视频或游戏中下一关所需的资源)存储数据,请查询volumeAvailableCapacityForImportantUsageKey. 但是,如果您以更具预测性的方式下载数据(例如,下载用户最近观看的电视剧的新剧集),请查询volumeAvailableCapacityForOpportunisticUsageKey.

构造查询

使用此示例作为构建您自己的查询的指南:

let fileURL = URL(fileURLWithPath:"/")
do {
    let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey])
    if let capacity = values.volumeAvailableCapacityForImportantUsage {
        print("Available capacity for important usage: \(capacity)")
    } else {
        print("Capacity is unavailable")
    }
} catch {
    print("Error retrieving capacity: \(error.localizedDescription)")
}
于 2018-01-10T17:45:44.310 回答
2

昨天发布的另一个问题已作为该问题的副本关闭,并且该问题展示了您可能弄错的另一种方式。

那位提问者的做法是:

uint64_t freeSpace = (uint64_t)[fileSystemAttributes objectForKey:NSFileSystemFreeSize];

NSLog(@"Free space in bytes: %lld.",freeSpace);

他们将对象本身(更准确地说,对象在内存中的地址)视为空闲字节数。这是错误的;该对象是一个 NSNumber 对象,它包装了这样一个数字。正确的代码会向对象询问它unsignedLongLongValue的​​类型,它的类型正确,因此大到足以容纳正确的值。

于 2012-12-18T05:56:43.223 回答
-2

我敢打赌,您正在使用 32 位整数或浮点类型来存储文件系统大小值。如果文件大小足够大,这将失败。相反,使用 unsigned long long 或 long double 类型来存储这些值。

有关如何准确读取这些文件大小的信息,请参阅此答案的更正版本。对该答案和其他答案的评论表明,这将返回一个与 iTunes 和其他工具报告的可用大小相匹配的值。

于 2012-08-01T15:12:38.900 回答