Frage

Im Moment verwende ich diesen Code, um die Größe eines Ordners zu bekommen:

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]; 

Das Problem ist, dass seine hoch innacurate. Sie fügt hinzu, entweder ein paar Megabyte oder zieht ein paar Megabyte von der tatsächlichen Größe. Zum Beispiel habe ich die Dateigröße eines .app Bündel und diese Methode berichtet 16.2MB, während die eigentliche Sache 15.8 ist.

Was ist der beste Weg, um die Größe eines Ordners zu bekommen?

Danke

War es hilfreich?

Lösung

Ich brauchte diese heute selbst zu tun, und ich habe festgestellt, dass der Code in dieser Beitrag auf der Liste Cocoa-Entwicklers ist super schnell und übereinstimmt, was in dem Byte-Finder sagt. (Vergessen Sie nicht, OR in der kFSCatInfoRsrcSizes Flagge, so dass Sie Resource Fork Größen bekommen, auch!)

Wenn Sie mehr Erklärung benötigen, wie es zu verwenden, lassen Sie einfach einen Kommentar und ich werde diesen Beitrag bearbeiten. =)

Andere Tipps

Die Dokumentation für fileSize heißt es, nicht die Größe einer Ressourcenzweig enthält. Sie können die Carbon-File Manager API verwenden müssen zuverlässig Verzeichnisgrößen zu berechnen.

Ich wollte nur zweiten Dave DeLong Vorschlag über die Post auf Cocoa-Entwickler, aber einen warnenden Hinweis hinzufügen, um sicherzustellen, dass alle Beiträge im Thread zu lesen. Es gibt eine von Rosyna, die besonders sind erwähnenswert. In meinem Fall folgte ich, dass die Beratung (Ändern max Artikels pro bis 40 holen) und sah auch einen Geschwindigkeitssprung als das Ende zu einem heftigen Krachen Fehlern.

Hoffnung dies helfen wird,

- (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;
}

Dies ist in der Regel, wie es gemacht wird. 2 Möglichkeiten:

  1. Überprüfen Sie die Byte -> Megabyte Konvertierungsroutinen. Außerdem wollen Sie Megabyte oder mebibytes? (Es hängt wahrscheinlich auf das, was Sie vergleichen es.)

  2. Versuchen Sie NO für den traverseLink Parameter. Es könnte sehr gut ein symbolischer Link im Bündel sein Hinweis auf etwas anderes, dass die Routine, die Sie es sind im Vergleich zu wird nicht zu berücksichtigen. Entweder wird zweimal etwas im Bündel zählen, oder du wirst ganz etwas außerhalb des Bündels enthält (wahrscheinlich die ehemalige).

Ich weiß, dass dies ist ein altes Thema. Aber für alle, die da draußen für Antworten darauf, wie dies zu tun,

[[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];
        }

Es wird Terminal verwenden, um eine Größe für Ordner in Bytes zu bestimmen. Und es wird Cocoa in NSFileManager gebaut, um die Größe von Dateien zu erhalten. Es ist sehr schnell, und wird die genaue Größe, die Berichte Finder.

Dieser Code ist als Erweiterung (Kategorie) an die NSFileManager Klasse. Es fasst die Größen aller Ordner-Inhalte.  Beachten Sie, dass Fehlerbehandlung verbessert werden kann.

 @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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top