Utwórz folder / katalog w Objective-C / cocoa

Mam ten kod do utworzenia folderu / katalogu w Objective-C / cocoa.

if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
        if(![fileManager createDirectoryAtPath:directory attributes:nil])
            NSLog(@"Error: Create folder failed %@", directory);
Działa dobrze, ale dostałem Ostrzeżenie. Jaki jest najnowszy sposób tworzenia kreatora katalogów w Cocoa / Objective-c?

Rozwiązany

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);
Author: nio, 2011-02-28

4 answers

 56
Author: Dave DeLong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-28 06:22:14

Twoje rozwiązanie jest poprawne, choć Apple zawiera ważną notatkę w 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;

Zasadniczo, jeśli wiele wątków/procesów modyfikuje system plików jednocześnie, stan może się zmienić pomiędzy wywołaniem fileExistsAtPath:isDirectory: i wywołaniem createDirectoryAtPath:withIntermediateDirectories:, więc wywołanie fileExistsAtPath:isDirectory: w tym kontekście jest zbędne i potencjalnie niebezpieczne.

Dla Twoich potrzeb i w ograniczonym zakresie twojego pytania prawdopodobnie nie byłoby to problemem, ale poniższe rozwiązanie jest zarówno prostsze, jak i oferuje mniej szans na przyszłe problemy:

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

Również notatka z dokumentacji Apple :

Return Value

Tak, jeśli katalog został utworzony, tak, jeśli ustawiono createIntermediates i katalog już istnieje), LUB NIE, jeśli wystąpił błąd.

Więc ustawienie createIntermediates na YES, co już robisz, jest de facto sprawdzeniem, czy katalog już istnieje.

 19
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-07 19:07:53

Pomyślałem, że dodam do tego i wspomnę trochę więcej z dokumentacji o używaniu metody + defaultManager:

w systemach iOS i Mac OS X v 10.5 i nowszych należy rozważyć użycie [[NSFileManager alloc] INIT] zamiast metody singleton defaultManager. Instancje NSFileManager są uważane za bezpieczne dla wątków, gdy są tworzone przy użyciu [[NSFileManager alloc] init].

 3
Author: August,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-13 22:08:59

Możesz wybrać metodę NSFileManager:

createDirectoryAtURL:withIntermediateDirectories:attributes:error:

Działa z adresami URL zamiast ciągów ścieżek.

 2
Author: Stephan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-30 05:59:47