jos*_*ney 66 iphone nsfilemanager ios
我正在创建一个文件夹,用我的iPhone App缓存Documents中的图像.我希望能够将此文件夹的大小保持在1MB,因此我需要检查文件夹的大小(以字节为单位).
最好的方法是什么?
Nik*_*uhe 68
所有其他答案都关闭:)
我想在这个老问题上加上我的两分钱,因为似乎有许多答案都非常相似,但产生的结果在某些情况下是非常不准确的.
要理解为什么我们首先要定义文件夹的大小.根据我的理解(可能是OP中的一个),它是包含其所有内容的目录在卷上使用的字节数.或者,换一种说法:
如果目录将被完全删除,则可用空间.
我知道这个定义并不是解释问题的唯一有效方法,但我认为这是大多数用例归结为的.
现有答案都采用一种非常简单的方法:遍历目录内容,累加(常规)文件的大小.这不需要考虑一些细微之处.
所有这些原因使得现有答案产生了不恰当的结果.所以我建议这个扩展NSFileManager
(github 上的代码由于长度:Swift 4,Objective C)来解决这个问题.它也快得多,特别是对于包含大量文件的目录.
该解决方案的核心是使用NSURL
的NSURLTotalFileAllocatedSizeKey
或NSURLFileAllocatedSizeKey
性的判定来检索文件的大小.
我还建立了一个简单的iOS测试项目,展示了解决方案之间的差异.它显示了在某些情况下结果的完全错误.
在测试中,我创建了一个包含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)
Run Code Online (Sandbox Code Playgroud)
jos*_*ney 42
那个亚历克斯的干杯,你帮了很多忙,现在已经写了下面的功能,这就是诀窍......
- (unsigned long long int)folderSize:(NSString *)folderPath {
NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
NSString *fileName;
unsigned long long int fileSize = 0;
while (fileName = [filesEnumerator nextObject]) {
NSDictionary *fileDictionary = [[NSFileManager defaultManager] fileAttributesAtPath:[folderPath stringByAppendingPathComponent:fileName] traverseLink:YES];
fileSize += [fileDictionary fileSize];
}
return fileSize;
}
Run Code Online (Sandbox Code Playgroud)
它提出了Finder所做的确切字节数.
另外,Finder返回两个数字.一个是磁盘上的大小,另一个是实际的字节数.
例如,当我在我的一个文件夹上运行此代码时,它返回代码中的'fileSize'为130398.当我检入Finder时,它表示磁盘上的大小为201KB(130,398字节).
我不确定这里有什么(201KB或130,398字节)作为实际尺寸.就目前而言,我会安全地将我的限制减半,直到我发现这意味着什么......
如果有人可以为这些不同的数字添加更多信息,我会很感激.
干杯,
The*_*ger 31
这是如何获得文件夹和文件size
的MB,KB和GB ---
1.文件夹大小 -
-(NSString *)sizeOfFolder:(NSString *)folderPath
{
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:nil];
NSEnumerator *contentsEnumurator = [contents objectEnumerator];
NSString *file;
unsigned long long int folderSize = 0;
while (file = [contentsEnumurator nextObject]) {
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:file] error:nil];
folderSize += [[fileAttributes objectForKey:NSFileSize] intValue];
}
//This line will give you formatted size from bytes ....
NSString *folderSizeStr = [NSByteCountFormatter stringFromByteCount:folderSize countStyle:NSByteCountFormatterCountStyleFile];
return folderSizeStr;
}
Run Code Online (Sandbox Code Playgroud)
注意:如果是子文件夹,请使用subpathsOfDirectoryAtPath:
而不是contentsOfDirectoryAtPath:
2.文件大小 -
-(NSString *)sizeOfFile:(NSString *)filePath
{
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
NSInteger fileSize = [[fileAttributes objectForKey:NSFileSize] integerValue];
NSString *fileSizeStr = [NSByteCountFormatter stringFromByteCount:fileSize countStyle:NSByteCountFormatterCountStyleFile];
return fileSizeStr;
}
Run Code Online (Sandbox Code Playgroud)
---------- Swift 4.0 ----------
1.文件夹大小 -
func sizeOfFolder(_ folderPath: String) -> String? {
do {
let contents = try FileManager.default.contentsOfDirectory(atPath: folderPath)
var folderSize: Int64 = 0
for content in contents {
do {
let fullContentPath = folderPath + "/" + content
let fileAttributes = try FileManager.default.attributesOfItem(atPath: fullContentPath)
folderSize += fileAttributes[FileAttributeKey.size] as? Int64 ?? 0
} catch _ {
continue
}
}
/// This line will give you formatted size from bytes ....
let fileSizeStr = ByteCountFormatter.string(fromByteCount: folderSize, countStyle: ByteCountFormatter.CountStyle.file)
return fileSizeStr
} catch let error {
print(error.localizedDescription)
return nil
}
}
Run Code Online (Sandbox Code Playgroud)
2.文件大小 -
func sizeOfFile(_ filePath: String) -> String? {
do {
let fileAttributes = try FileManager.default.attributesOfItem(atPath: filePath)
let folderSize = fileAttributes[FileAttributeKey.size] as? Int64 ?? 0
let fileSizeStr = ByteCountFormatter.string(fromByteCount: folderSize, countStyle: ByteCountFormatter.CountStyle.file)
return fileSizeStr
} catch {
print(error)
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
ndo*_*doc 30
在iOS 5中,该方法-filesAttributesAtPath:
已弃用.以下是使用新方法发布的第一个代码的版本:
- (unsigned long long int)folderSize:(NSString *)folderPath {
NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
NSString *fileName;
unsigned long long int fileSize = 0;
while (fileName = [filesEnumerator nextObject]) {
NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:fileName] error:nil];
fileSize += [fileDictionary fileSize];
}
return fileSize;
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*lds 10
以下内容应该有助于您入门.但是,您需要修改_documentsDirectory
到您的特定文件夹:
- (unsigned long long int) documentsFolderSize {
NSFileManager *_manager = [NSFileManager defaultManager];
NSArray *_documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *_documentsDirectory = [_documentPaths objectAtIndex:0];
NSArray *_documentsFileList;
NSEnumerator *_documentsEnumerator;
NSString *_documentFilePath;
unsigned long long int _documentsFolderSize = 0;
_documentsFileList = [_manager subpathsAtPath:_documentsDirectory];
_documentsEnumerator = [_documentsFileList objectEnumerator];
while (_documentFilePath = [_documentsEnumerator nextObject]) {
NSDictionary *_documentFileAttributes = [_manager fileAttributesAtPath:[_documentsDirectory stringByAppendingPathComponent:_documentFilePath] traverseLink:YES];
_documentsFolderSize += [_documentFileAttributes fileSize];
}
return _documentsFolderSize;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
36376 次 |
最近记录: |