7

现在我正在使用此代码来获取文件夹的大小:

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。

获取文件夹大小的最佳方法是什么?

谢谢

4

7 回答 7

7

我今天需要自己做这个,我发现Cocoa-dev 列表上这篇文章中的代码非常快,并且与 Finder 对字节的说法相匹配。(不要忘记在 kFSCatInfoRsrcSizes 标志中进行 OR 操作,这样您也可以获得资源分叉大小!)

如果您需要有关如何使用它的更多说明,请发表评论,我将编辑此帖子。=)

于 2009-08-14T04:26:25.687 回答
4

说明它的文档fileSize不包括资源分叉的大小。您可能需要使用Carbon File Manager API来可靠地计算目录大小。

于 2009-08-14T01:48:02.883 回答
2

我只是想支持 Dave DeLong 关于 Cocoa-dev 上的帖子的建议,但添加一个警告说明以确保阅读线程中的所有帖子。Rosyna 有一个特别值得注意。就我而言,我遵循了该建议(将每次提取的最大项目数更改为 40),并看到了速度的飞跃以及令人讨厌的崩溃错误的结束。

于 2009-08-14T05:57:05.103 回答
2

希望这会有所帮助

- (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;
}
于 2016-10-14T13:41:09.373 回答
1

这通常是如何完成的。2种可能性:

  1. 检查您的字节-> 兆字节转换例程。另外,你想要兆字节还是兆字节?(这可能取决于您将其与什么进行比较。)

  2. traverseLink尝试为参数传递 NO 。捆绑包中很可能有一个符号链接指向您与之比较的例程无法解释的其他内容。您要么将捆绑包中的某些内容计算两次,要么将捆绑包之外的内容完全包含在内(很可能是前者)。

于 2009-08-14T01:46:20.700 回答
1

我知道这是一个老话题。但是对于那些正在寻找如何做到这一点的答案的人来说,

[[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 报告的确切大小。

于 2010-01-19T13:17:53.523 回答
1

此代码作为 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
于 2012-12-03T16:48:09.087 回答