我正在使用我的 iPhone 应用程序创建一个文件夹来缓存 Documents 中的图像。我希望能够将此文件夹的大小保持在 1MB,因此我需要检查我的文件夹的大小(以字节为单位)。
我有计算 size of file 的代码, 但我需要文件夹的大小。
执行此操作的最佳方法是什么?
最佳答案
tl;博士
所有其他答案均已关闭 :)
问题
我想对这个老问题补充我的两分钱,因为似乎有很多答案都非常相似,但在某些情况下产生的结果非常不精确。
要理解为什么我们首先必须定义文件夹的大小。根据我的理解(可能是 OP 中的一个),它是包含其所有内容的目录在卷上使用的字节数。或者,换句话说:
如果目录将被完全删除,它是可用的空间。
我知道这个定义不是解释问题的唯一有效方式,但我确实认为这是大多数用例的归结。
错误
现有的答案都采用了一种非常简单的方法:遍历目录内容,将(常规)文件的大小相加。这并没有考虑到一些微妙之处。
- 卷上使用的空间以 block 而不是字节为单位递增。即使一个字节的文件也至少使用一个 block 。
- 文件携带元数据(如任意数量的扩展属性)。这些数据必须去某个地方。
- HFS 部署文件系统压缩,以使用比实际长度更少的字节实际存储文件。
解决方案
所有这些原因导致现有答案产生不精确的结果。所以我在 NSFileManager
上提出这个扩展(由于长度在 github 上的代码:Swift 4,Objective C)来解决这个问题。它也快了很多,尤其是对于包含大量文件的目录。
解决方案的核心是使用 NSURL
的 NSURLTotalFileAllocatedSizeKey
或 NSURLFileAllocatedSizeKey
属性来检索文件大小。
测试
我还设置了 a simple iOS test project ,展示解决方案之间的差异。它显示了在某些情况下结果可能是多么错误。
在测试中,我创建了一个包含 100 个小文件(从 0 到 800 字节不等)的目录。从其他答案复制的 folderSize:
方法计算出总共 21 kB,而我的 allocatedSize
方法产生 401 kB。
证明
我通过计算删除测试目录前后卷上可用字节的差异,确保 allocatedSize
的结果更接近正确值。在我的测试中,差异总是完全等于 allocatedSize
的结果。
请查看 Rob Napier 的评论以了解仍有改进空间。
性能
但还有另一个优势:在计算包含 1000 个文件的目录大小时,在我的 iPhone 6 上,folderSize:
方法大约需要 250 毫秒,而 allocatedSize
遍历相同的时间35 毫秒内的层次结构。
这可能是由于使用 NSFileManager
的新(ish)enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:
API 来遍历层次结构。此方法让您可以为要迭代的项目指定预取属性,从而减少 io。
结果
Test `folderSize` (100 test files)
size: 21 KB (21.368 bytes)
time: 0.055 s
actual bytes: 401 KB (401.408 bytes)
Test `allocatedSize` (100 test files)
size: 401 KB (401.408 bytes)
time: 0.048 s
actual bytes: 401 KB (401.408 bytes)
Test `folderSize` (1000 test files)
size: 2 MB (2.013.068 bytes)
time: 0.263 s
actual bytes: 4,1 MB (4.087.808 bytes)
Test `allocatedSize` (1000 test files)
size: 4,1 MB (4.087.808 bytes)
time: 0.034 s
actual bytes: 4,1 MB (4.087.808 bytes)
关于ios - 如何计算文件夹的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2188469/