获取文件夹大小的简单方法(ObjC/Cocoa)?
-
16-09-2019 - |
题
现在我正在使用此代码来获取文件夹的大小:
NSArray *contents;
NSEnumerator *enumerator;
NSString *path;
contents = [[NSFileManager defaultManager] subpathsAtPath:folderPath];
enumerator = [contents objectEnumerator];
while (path = [enumerator nextObject]) {
NSDictionary *fattrib = [[NSFileManager defaultManager] fileAttributesAtPath:[folderPath stringByAppendingPathComponent:path] traverseLink:YES];
fileSize +=[fattrib fileSize];
}
[contents release];
[path release];
问题是它非常不准确。它要么增加几兆字节,要么从实际大小中减去几兆字节。例如,我获取了 .app 捆绑包的文件大小,此方法报告为 16.2MB,而实际大小为 15.8。
获取文件夹大小的最佳方法是什么?
谢谢
解决方案
我需要做今天这个我自己,而且我发现的这个职位上的可可开发列表是超级快,匹配查找什么说的字节。 (所以你得到的资源叉的大小不要忘记或kFSCatInfoRsrcSizes标志,太!)
如果您需要关于如何使用它更多的解释,只是发表评论,我会编辑这个职位。 =)
其他提示
有fileSize
文档状态不包括资源派生的大小。您可能需要使用碳文件管理器API 可靠地计算目录大小。
我只是想第二戴夫德隆的有关可可-dev的帖子建议,但增加一个风险提示请务必仔细阅读线程中的所有职务。有一个由Rosyna这是特别值得一提。在我来说,我跟着他的意见(改变最大的项目每取40),看到一个速度跳以及一个讨厌的崩溃错误结束。
希望这将有助于
- (unsigned long long) fastFolderSizeAtFSRef:(NSString *)theFilePath
{
unsigned long long totalSize = 0;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isdirectory;
NSError *error;
if ([fileManager fileExistsAtPath:theFilePath])
{
NSMutableArray * directoryContents = [[fileManager contentsOfDirectoryAtPath:theFilePath error:&error] mutableCopy];
for (NSString *fileName in directoryContents)
{
if (([fileName rangeOfString:@".DS_Store"].location != NSNotFound) )
continue;
NSString *path = [theFilePath stringByAppendingPathComponent:fileName];
if([fileManager fileExistsAtPath:path isDirectory:&isdirectory] && isdirectory )
{
totalSize = totalSize + [self fastFolderSizeAtFSRef:path];
}
else
{
unsigned long long fileSize = [[fileManager attributesOfItemAtPath:path error:&error] fileSize];
totalSize = totalSize + fileSize;
}
}
}
return totalSize;
}
这通常是如何完成的。2种可能性:
检查您的字节 -> 兆字节转换例程。另外,您想要兆字节还是兆字节?(这可能取决于您将其与什么进行比较。)
尝试传递 NO
traverseLink
范围。捆绑包中很可能有一个符号链接指向您与之比较的例程无法解释的其他内容。您要么将捆绑包中的某些内容计算两次,要么将完全包含在捆绑包之外的某些内容(很可能是前者)。
我知道这是一个老话题。但没有人在那里寻找如何做到这一点的答案,
[[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
if (isDir) {
NSPipe *pipe = [NSPipe pipe];
NSTask *t = [[[NSTask alloc] init] autorelease];
[t setLaunchPath:@"/usr/bin/du"];
[t setArguments:[NSArray arrayWithObjects:@"-k", @"-d", @"0", path, nil]];
[t setStandardOutput:pipe];
[t setStandardError:[NSPipe pipe]];
[t launch];
[t waitUntilExit];
NSString *sizeString = [[[NSString alloc] initWithData:[[pipe fileHandleForReading] availableData] encoding:NSASCIIStringEncoding] autorelease];
sizeString = [[sizeString componentsSeparatedByString:@" "] objectAtIndex:0];
bytes = [sizeString longLongValue]*1024;
}
else {
bytes = [[[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil] fileSize];
}
它将使用终端来确定大小以字节的文件夹。它将利用可可的内置的NSFileManager获取文件的大小。它的速度非常快,并获取寻人报告的确切大小。
此码作为扩展(类别)到的NSFileManager类。它总结所有文件夹内容的大小。 注意,错误处理可以得到加强。
@interface NSFileManager(Util)
- (NSNumber *)sizeForFolderAtPath:(NSString *) source error:(NSError **)error;
@end
@implementation NSFileManager(Util)
- (NSNumber *)sizeForFolderAtPath:(NSString *) source error:(NSError **)error
{
NSArray * contents;
unsigned long long size = 0;
NSEnumerator * enumerator;
NSString * path;
BOOL isDirectory;
// Determine Paths to Add
if ([self fileExistsAtPath:source isDirectory:&isDirectory] && isDirectory)
{
contents = [self subpathsAtPath:source];
}
else
{
contents = [NSArray array];
}
// Add Size Of All Paths
enumerator = [contents objectEnumerator];
while (path = [enumerator nextObject])
{
NSDictionary * fattrs = [self attributesOfItemAtPath: [ source stringByAppendingPathComponent:path ] error:error];
size += [[fattrs objectForKey:NSFileSize] unsignedLongLongValue];
}
// Return Total Size in Bytes
return [ NSNumber numberWithUnsignedLongLong:size];
}
@end