75

iPhone アプリでドキュメント内の画像をキャッシュするフォルダーを作成しています。このフォルダーのサイズを 1 MB に抑えたいので、フォルダーのサイズをバイト単位で確認する必要があります。

fileのサイズを計算するコードがありますが、フォルダーのサイズが必要です。

これを行う最良の方法は何ですか?

4

15 に答える 15

43

そのアレックスに乾杯、あなたはたくさん助けてくれました。今、トリックを行う次の関数を書きました...

- (unsigned long long int)folderSize:(NSString *)folderPath {
    NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
    NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
    NSString *fileName;
    unsigned long long int fileSize = 0;

    while (fileName = [filesEnumerator nextObject]) {
        NSDictionary *fileDictionary = [[NSFileManager defaultManager] fileAttributesAtPath:[folderPath stringByAppendingPathComponent:fileName] traverseLink:YES];
        fileSize += [fileDictionary fileSize];
    }

    return fileSize;
}

Finder と同じように、正確なバイト数が表示されます。

余談ですが、Finder は 2 つの数値を返します。1 つはディスク上のサイズで、もう 1 つは実際のバイト数です。

たとえば、フォルダーの 1 つでこのコードを実行すると、「fileSize」が 130398 でコードに返されます。

ここで実際のサイズ (201KB または 130,398 バイト) をどうするか少しわかりません。今のところ、これが何を意味するのかが正確にわかるまで、安全のために制限を半分に減らします...

誰かがこれらの異なる数字にさらに情報を追加できるなら、私はそれを感謝します.

乾杯、

于 2010-02-03T02:21:37.267 に答える
30

iOS 5では、このメソッド-filesAttributesAtPath:は非推奨になりました。新しいメソッドで投稿された最初のコードのバージョンは次のとおりです。

- (unsigned long long int)folderSize:(NSString *)folderPath {
    NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
    NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
    NSString *fileName;
    unsigned long long int fileSize = 0;

    while (fileName = [filesEnumerator nextObject]) {
        NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:fileName] error:nil];
        fileSize += [fileDictionary fileSize];
    }

    return fileSize;
}
于 2012-06-28T18:25:25.097 に答える
11

次のようなものはあなたが始めるのに役立つはずです。_documentsDirectoryただし、特定のフォルダに変更する必要があります。

- (unsigned long long int) documentsFolderSize {
    NSFileManager *_manager = [NSFileManager defaultManager];
    NSArray *_documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *_documentsDirectory = [_documentPaths objectAtIndex:0];   
    NSArray *_documentsFileList;
    NSEnumerator *_documentsEnumerator;
    NSString *_documentFilePath;
    unsigned long long int _documentsFolderSize = 0;

    _documentsFileList = [_manager subpathsAtPath:_documentsDirectory];
    _documentsEnumerator = [_documentsFileList objectEnumerator];
    while (_documentFilePath = [_documentsEnumerator nextObject]) {
        NSDictionary *_documentFileAttributes = [_manager fileAttributesAtPath:[_documentsDirectory stringByAppendingPathComponent:_documentFilePath] traverseLink:YES];
        _documentsFolderSize += [_documentFileAttributes fileSize];
    }

    return _documentsFolderSize;
}
于 2010-02-03T00:46:47.313 に答える
4

このコードを使用して、2 つのディレクトリのディレクトリ サイズを取得しました。1 つのディレクトリが存在しない場合は、ゼロ KB と表示されます。それ以外の場合、コードの後半では、フォルダ サイズがそれぞれ KB、MB、GB とともに表示され、クリーンな形式で表示されます: 10.02 MB.

これを次のように試してください:

- (unsigned long long int)folderSize:(NSString *)folderPath {
    NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
    NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
    NSString *fileName;
    unsigned long long int fileSize = 0;

    while (fileName = [filesEnumerator nextObject]) {
        NSDictionary *fileDictionary = [[NSFileManager defaultManager] fileAttributesAtPath:[folderPath stringByAppendingPathComponent:fileName] traverseLink:YES];
        fileSize += [fileDictionary fileSize];
    } 

    return fileSize;
}

-(NSString *)getMPSize
{
    NSString*sizeTypeW = @"bytes";
    int app = [self folderSize:@"/PathToTheFolderYouWantTheSizeOf/"];
    NSFileManager *manager = [NSFileManager defaultManager];
    if([manager fileExistsAtPath:@"/AnotherFolder/"] == YES){

        int working = [self folderSize:@"/AnotherFolder/"];
        if(working<1){
            return @"Size: Zero KB";
        }else{
            if (working > 1024)
            {
                //Kilobytes
                working = working / 1024;

                sizeTypeW = @" KB";
            }

            if (working > 1024)
            {
                //Megabytes
                working = working / 1024;

                sizeTypeW = @" MB";
            }

            if (working > 1024)
            {
                //Gigabytes
                working = working / 1024;

                sizeTypeW = @" GB";
            }

            return [NSString stringWithFormat:@"App: %i MB, Working: %i %@ ",app/1024/1024, working,sizeTypeW];
        }

    }else{
        return [NSString stringWithFormat:@"App: %i MB, Working: Zero KB",app/1024/1024];
    }
    [manager release];
}
于 2011-02-15T02:12:46.480 に答える
1

最初の回答の実装を使用する前に少しクリーンアップしたため、非推奨の警告がスローされなくなり、高速列挙が使用されなくなりました。

/**
 *  Calculates the size of a folder.
 *
 *  @param  folderPath  The path of the folder
 *
 *  @return folder size in bytes
 */
- (unsigned long long int)folderSize:(NSString *)folderPath {
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray *filesArray = [fm subpathsOfDirectoryAtPath:folderPath error:nil];
    unsigned long long int fileSize = 0;

    NSError *error;
    for(NSString *fileName in filesArray) {
        error = nil;
        NSDictionary *fileDictionary = [fm attributesOfItemAtPath:[folderPath     stringByAppendingPathComponent:fileName] error:&error];
        if (!error) {
            fileSize += [fileDictionary fileSize];
        }else{
            NSLog(@"ERROR: %@", error);
        }
    }

    return fileSize;
}
于 2013-07-25T09:30:03.803 に答える
1

ファイルのサイズを取得したい場合は、そのファイルのパスを渡すだけでよい方法があります。

- (unsigned long long int) fileSizeAt:(NSString *)path {
    NSFileManager *_manager = [NSFileManager defaultManager];
    return [[_manager fileAttributesAtPath:path traverseLink:YES] fileSize];
}
于 2012-04-02T08:53:46.180 に答える
0

これが誰かに役立つかどうかはわかりませんが、私の調査結果の一部を関連付けたいと思いました (上記の @zneak のコメントに触発されたものもあります)。

  1. NSDirectoryEnumeratorディレクトリに含まれる合計サイズを取得するためにファイルを列挙するのを避けるために使用するショートカットが見つかりませんでした。

  2. 私のテストでは、 を使用-[NSFileManager subpathsOfDirectoryAtPath:path error:nil]するよりも を使用する方が高速でし-[NSFileManager enumeratorAtPath:path]た。subPaths...これは、NSArray を作成してから反復処理するため、古典的な時間/空間のトレードオフのように見えますが、そうでenumerator...ない場合もあります。

#1の背景。仮定:

NSFileManager *fileMan = [NSFileManager defaultManager];
NSString *dirPath = @"/"; // references some directory

それで

[fileMan enumeratorAtPath:dirPath] fileAttributes]

戻りますnil。正しい属性アクセサーは ですdirectoryAttributesが、

[fileMan enumeratorAtPath:dirPath] directoryAttributes] fileSize]

含まれているすべてのファイルのサイズの再帰的な合計ではなく、ディレクトリ情報のサイズを返します (Finder の lá ⌘-I)。

于 2012-08-23T17:54:21.840 に答える
0

簡単な NSFileManager 拡張機能を作成しました。

extension NSFileManager {
  func fileSizeAtPath(path: String) -> Int {
    return attributesOfItemAtPath(path, error: nil)?[NSFileSize] as? Int ?? 0
  }

  func folderSizeAtPath(path: String) -> Int {
    var size = 0
    for file in subpathsOfDirectoryAtPath(path, error: nil) as? [String] ?? [] {
      size += fileSizeAtPath(path.stringByAppendingPathComponent(file))
    }
    return size
  }
}

ファイルサイズを取得できます:

NSFileManager.defaultManager().fileSizeAtPath("file path")

およびフォルダーのサイズ:

NSFileManager.defaultManager().folderSizeAtPath("folder path")
于 2015-08-21T14:47:43.370 に答える