[英]Easy way to get size of folder (ObjC/Cocoa)?
现在我正在使用此代码来获取文件夹的大小:
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。
获取文件夹大小的最佳方法是什么?
谢谢
我今天需要自己做这个,并且我发现Cocoa-dev列表中这篇文章中的代码非常快,并且匹配Finder对字节所说的内容。 (不要忘记在kFSCatInfoRsrcSizes标志中使用OR,这样你也可以获得资源分叉大小!)
如果您需要有关如何使用它的更多解释,请发表评论,我将编辑此帖。 =)
fileSize
的文档声明它不包括资源fork的大小。 您可能需要使用Carbon File Manager API来可靠地计算目录大小。
我只是想对Dave DeLong关于Cocoa-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种可能性:
检查你的字节 - >兆字节转换例程。 此外,你想要兆字节还是mebibytes? (这可能取决于你要比较的东西。)
尝试为traverseLink
参数传递NO。 在捆绑中可能有一个符号链接指向您正在比较它的例程将不会考虑的其他内容。 你要么在捆绑中计算两次,要么完全包括捆绑之外的东西(很可能是前者)。
此代码作为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
我知道这是一个古老的话题。 但对于那里的任何人寻找如何做到这一点的答案,
[[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];
}
它将使用终端来确定文件夹的大小(以字节为单位)。 它将使用Cocoa内置的NSFileManager来获取文件的大小。 它非常快,并且获得了finder报告的确切大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.