7
votes

Un moyen facile d'obtenir la taille du dossier (objc / cacao)?

En ce moment, j'utilise ce code pour obtenir la taille d'un dossier:

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


1 commentaires

Quelqu'un en utilisant ceci sous Sandboxing? :-)


7 Réponses :


1
votes

Ceci est typiquement comment cela se fait. 2 possibilités:

  1. Vérifiez votre octet -> routines de conversion mégaoctet. Aussi, tu veux des mégaoctets ou des mébibytes? (Cela dépend probablement de ce que vous comparez à.)

  2. Essayez de passer non pour le paramètre trapherselink . Il se peut très bien être un lien symbolique dans le paquet pointant vers quelque chose d'autre que la routine que vous comparez pour ne présentera pas. Vous compterez deux fois dans le paquet deux fois, ou vous inclurez quelque chose en dehors du faisceau entièrement (probablement le premier).


0 commentaires

4
votes

La documentation de FileLesize Les états n'incluent pas la taille d'une fourchette de ressource. Vous devrez peut-être utiliser le API calculer de manière fiable des tailles de répertoires.


1 commentaires

Ah oui, c'est une autre possibilité. J'ai oublié cela.



7
votes

J'avais besoin de le faire aujourd'hui moi-même, et j'ai trouvé que le code dans Cet article sur la liste COCOA-DEV est super rapide et correspond à quel Finder dit à l'octet. (N'oubliez pas de ou dans le drapeau KFscAtinforsRcsises afin que vous obteniez des tailles de fourche de ressources aussi!)

Si vous avez besoin de plus d'explications sur la façon de l'utiliser, laissez simplement un commentaire et je modifierai ce message. =)


7 commentaires

Merci, qu'est-ce qu'un bon moyen de convertir une nstring contenant un chemin vers un FSRef? Merci


Je viens de répondre à votre question. =)


@Dave, ce lien est cassé, pourriez-vous les mettre à jour ou le code pour répondre?


@Igor fixe avec un lien archive.org


Merci pour une réponse rapide!


Pensez-vous que c'est toujours à jour une solution?


Fondamentalement, probablement. Il est possible que des portions possibles de l'API ont été remplacées au cours des 12 dernières années;)



2
votes

Je voulais juste une deuxième suggestion de Dave Delong sur le poste sur Cocoa-Dev, mais ajoutez une note de précaution pour vous assurer de lire tous les messages du fil. Il y en a un de Rosyna qui vaut particulièrement la peine d'être noté. Dans mon cas, j'ai suivi ce conseil (changeant des articles maximum par récupération à 40) et vu un saut de vitesse ainsi que la fin d'un bogue de crash méchant.


2 commentaires

Peut-être préférable d'ajouter cela comme un commentaire à sa réponse afin qu'ils restent liés, même comme leurs positions sur le changement de page.


J'ai des problèmes avec la méthode de Dave Delong. J'utilise ce code pour convertir mon nstring en une FSREF: FSRef F; Ostatus os_status = fspathmakeref ((const uint8 *) [FilePath FileSystemrePresentation], & f, null); if (os_status == noerr) {nslog (@ "succès"); } Et puis j'essaie d'exécuter la méthode: [auto-fastfoldersAftFsrefsref: f]; Cependant, je reçois l'erreur "Type incompatible pour l'argument 1 de" FastDeFretersize "" Des idées? Merci



1
votes

Je sais que c'est un vieux sujet. Mais pour que quiconque cherche des réponses sur la façon de faire cela,

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


1 commentaires

Bien que cela fonctionne certainement, vous avez le succès de la performance de la création d'un autre processus (qui peut être assez coûteux) ou d'utiliser nsfilemanager , qui n'inclut pas les fourches de ressources lors du calcul de la taille.



1
votes

Ce code est en tant qu'extension (catégorie) de la classe NsfileManager. Il résume les tailles de tout contenu de dossier. Notez que le traitement d'erreur pourrait être amélioré.

 @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


0 commentaires

2
votes

J'espère que cela aidera

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


0 commentaires