48 votes

Créer un dossier / répertoire dans Objective-C / cacoa

J'ai ce code pour créer un dossier / répertoire dans Objective-C / cocoa.

 if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
        if(![fileManager createDirectoryAtPath:directory attributes:nil])
            NSLog(@"Error: Create folder failed %@", directory);
 

Cela fonctionne bien, mais j'ai reçu un message d'avertissement creatDirectoryAtPath:attributes is deprecated . Quelle est la dernière façon de créer un constructeur de répertoires dans Cocoa / Objective-c?

Résolu

 BOOL isDir;
NSFileManager *fileManager= [NSFileManager defaultManager]; 
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
    if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
        NSLog(@"Error: Create folder failed %@", directory);
 

58voto

Dave DeLong Points 156978

20voto

Matt Points 1068

Votre solution est correcte, même si Apple inclut une remarque importante au sein d' NSFileManager.h:

/* The following methods are of limited utility. Attempting to predicate behavior 
based on the current state of the filesystem or a particular file on the 
filesystem is encouraging odd behavior in the face of filesystem race conditions. 
It's far better to attempt an operation (like loading a file or creating a 
directory) and handle the error gracefully than it is to try to figure out ahead 
of time whether the operation will succeed. */

- (BOOL)fileExistsAtPath:(NSString *)path;
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;
- (BOOL)isReadableFileAtPath:(NSString *)path;
- (BOOL)isWritableFileAtPath:(NSString *)path;
- (BOOL)isExecutableFileAtPath:(NSString *)path;
- (BOOL)isDeletableFileAtPath:(NSString *)path;

Essentiellement, si plusieurs threads/processus sont en train de modifier le système de fichiers simultanément, l'état peut changer entre les appelant fileExistsAtPath:isDirectory: et en appelant createDirectoryAtPath:withIntermediateDirectories:, de sorte qu'il est superflu et peut-être dangereux pour appeler fileExistsAtPath:isDirectory: dans ce contexte.

Pour répondre à vos besoins et au sein de la portée limitée de votre question, il probablement ne serait pas un problème, mais la solution suivante est à la fois plus simple et offre moins de chance de futurs problèmes découlant:

NSFileManager *fileManager= [NSFileManager defaultManager];
NSError *error = nil;
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) {
     // An error has occurred, do something to handle it
     NSLog(@"Failed to create directory \"%@\". Error: %@", directory, error);
}

Notez également de la documentation d'Apple:

Valeur De Retour

OUI si le répertoire a été créé, OUI si createIntermediates est réglé et le répertoire existe déjà), ou PAS si une erreur s'est produite.

Donc, paramètre createIntermediates de YES, qui vous le font déjà, est de facto vérifier si le répertoire existe déjà.

3voto

August Points 140

Je pensais que j'ajouterais quelque chose à la documentation sur l'utilisation de la méthode + defaultManager:

Sous iOS et Mac OS X v 10.5 et versions ultérieures, vous devez envisager d'utiliser [[NSFileManager alloc] init] plutôt que la méthode singleton defaultManager. Les instances de NSFileManager sont considérées comme sûres pour les threads lorsqu'elles ont été créées à l'aide de [[NSFileManager alloc] init].

3voto

Stephan Points 1274

Vous préférerez peut-être utiliser la méthode NSFileManager :

createDirectoryAtURL:withIntermediateDirectories:attributes:error:

Cela fonctionne avec les URL au lieu des chaînes de chemin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X