Есть ли более безопасный способ создать каталог, если он не существует? - PullRequest
36 голосов
/ 25 мая 2011

Я нашел этот способ создания каталога, если он не существует.Но это выглядит немного странно, и я боюсь, что это может пойти не так в 1 из 1000 попыток.

if(![[NSFileManager defaultManager] fileExistsAtPath:bundlePath]) {
    [[NSFileManager defaultManager] createDirectoryAtPath:bundlePath withIntermediateDirectories:YES attributes:nil error:NULL];
}

Существует только этот неловкий метод fileExistsAtPath, который также ищет файлы, а не только каталоги.Но для меня опасная вещь: что, если это пойдет не так?Что мне делать?Как лучше всего гарантировать, что каталог создается и создается только тогда, когда он не существует?

Я знаю, что операции с файловой системой никогда не являются безопасными.Устройство может внезапно потерять заряд батареи как раз в тот момент, когда оно начнет переложить биты от А к В. Или оно может наткнуться на плохой бит и зависнуть на секунду.Возможно, в некоторых редких случаях он возвращает YES, даже если директории нет.Проще говоря: я не доверяю операциям с файловой системой.

Как я могу сделать это абсолютно безопасным?

Ответы [ 5 ]

77 голосов
/ 25 мая 2011

На самом деле вы можете пропустить if, хотя в документах Apple говорится, что каталог не должен существовать , это верно только в том случае, если вы передаете withIntermediateDirectories:NO

Это сводит его к одному звонку. Следующим шагом является обнаружение любых ошибок:

NSError * error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:bundlePath
                          withIntermediateDirectories:YES
                                           attributes:nil
                                                error:&error];
if (error != nil) {
    NSLog(@"error creating directory: %@", error);
    //..
}

Это не приведет к ошибке, если каталог уже существует.

6 голосов
/ 26 ноября 2016

для Swift 3.0

do {
    try FileManager.default.createDirectory(atPath: folder, withIntermediateDirectories: true, attributes: nil)
} catch {
    print(error)
}
3 голосов
/ 25 мая 2011
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);

Из раздела SO здесь .

После создания каталога вы можете очистить файловую систему, а затем проверить, существует ли созданный вами новый каталог.Это, вероятно, излишне, но слишком много не бывает.

1 голос
/ 29 ноября 2015

В Swift 2 это выглядит так:

do {
    try NSFileManager.defaultManager().createDirectoryAtPath(pathURL.absoluteString, withIntermediateDirectories: true, attributes: nil)
} catch {
    print(error)
}
0 голосов
/ 20 ноября 2018

Swift 4,2

let fileManager = FileManager.default
let documentsURL =  fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!

let imagesPath = documentsURL.appendingPathComponent("Images")
do
{
    try FileManager.default.createDirectory(atPath: imagesPath.path, withIntermediateDirectories: true, attributes: nil)
}
catch let error as NSError
{
    NSLog("Unable to create directory \(error.debugDescription)")
}
...