Objective c 获取文件夹大小的简单方法(ObjC/Cocoa)?
现在,我正在使用以下代码获取文件夹的大小:Objective c 获取文件夹大小的简单方法(ObjC/Cocoa)?,objective-c,cocoa,size,directory,nsfilemanager,Objective C,Cocoa,Size,Directory,Nsfilemanager,现在,我正在使用以下代码获取文件夹的大小: NSArray *contents; NSEnumerator *enumerator; NSString *path; contents = [[NSFileManager defaultManager] subpathsAtPath:folderPath]; enumerator = [contents objectEnumerator]; while (path =
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
获取文件夹大小的最佳方法是什么
谢谢这通常是这样做的。2种可能性:
traverseLink
参数传递NO。捆绑包中很可能有一个符号链接指向您正在比较它的例程无法解释的其他东西。您可以将捆绑包中的某些内容计数两次,或者将捆绑包之外的内容全部包括在内(很可能是前者)fileSize
的文档说明它不包括资源叉的大小。您可能需要使用来可靠地计算目录大小。我今天自己也需要这样做,我发现中的代码速度非常快,并且与Finder所说的字节相匹配。(不要忘了在kFSCatInfoRsrcSizes标志中添加或,这样也可以获得资源叉大小!)
如果您需要更多关于如何使用它的解释,请留下评论,我将编辑此帖子。=) 我只是想支持戴夫·德隆关于Cocoa dev上帖子的建议,但添加了一条警告,确保阅读帖子中的所有帖子。Rosyna的一篇文章特别值得一提。在我的例子中,我遵循了这个建议(将每次抓取的最大项目数更改为40),看到了一个速度提升以及一个令人讨厌的崩溃错误的结束。我知道这是一个老话题。但是对于那些想知道怎么做的人来说
[[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报告的确切大小。此代码作为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
希望这会有所帮助
- (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;
}
啊,是的,那是另一种可能性。我忘了。最好在他的回答中加上这个作为评论,这样即使他们在页面上的位置发生变化,他们也能保持联系。我对戴夫·德隆的方法有问题。我使用此代码将NSString转换为FSRef:FSRef f;OSStatus os_status=FSPathMakeRef((const UInt8*)[filePath fileSystemRepresentation],&f,NULL);如果(os_status==noErr){NSLog(@“Success”);},然后我尝试运行方法:[self-fastFolderSizeAtFSRef:f];但是我得到了错误“fastFolderSize参数1的类型不兼容”有什么想法吗?谢谢,把包含路径的NSString转换成FSRef的好方法是什么?谢谢你回答了你的问题。=)@Dave,此链接已断开,您可以更新它或放置代码来回答吗?@Igor已修复w/an archive.org链接感谢您的快速回复!虽然这肯定会起作用,但创建另一个进程(可能会非常昂贵)或使用
NSFileManager
(在计算大小时不包括资源分叉)会对性能造成影响。有人在沙箱下使用它吗?:-)