フォルダー(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.2 MB と報告されましたが、実際のサイズは 15.8 MB でした。
フォルダーのサイズを取得する最良の方法は何ですか?
ありがとう
解決
私はこの今日自分自身を行うために必要な、と私は<のhref = "http://web.archive.org/web/20080907020151/http://www.cocoabuilder.com/archiveのコードは検出されませんでした/メッセージ/ココア/ 2005/5/136503分の20" のrel = "nofollowをnoreferrer">ココア-devメーリングリストの上でこのポストは、超高速で、Finderがバイトに言うことを一致します。 (あなたはリソースフォークのサイズを取得するので、あまりにも、kFSCatInfoRsrcSizesフラグをORして忘れないように!)
あなたがそれを使用する方法の詳細な説明が必要な場合は、、ちょうどコメントを残して、私はこの記事を編集します。 =)
他のヒント
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
パラメータ。バンドル内に、比較対象のルーチンでは考慮されない別のものを指すシンボリックリンクが存在する可能性があります。バンドル内の何かを 2 回カウントするか、バンドルの外側にあるものを完全に含めることになります (おそらく前者)。
私は、これは古い話題であることを知っています。しかし、誰のためにそこにこれを行う方法の答えを探して、
[[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に建設を使用します。それは非常に高速だし、レポートをファインダー正確なサイズを取得します。
このコードは、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