ios 如果目录不存在,是否有更安全的方法来创建目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6125819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:05:21  来源:igfitidea点击:

Is there a safer way to create a directory if it does not exist?

iosobjective-cfilesystemsnsfilemanagernsdocumentdirectory

提问by dontWatchMyProfile

I've found this way of creating a directory if it does not exist. But it looks a bit wonky and I am afraid that this can go wrong in 1 of 1000 attempts.

如果目录不存在,我已经找到了这种创建目录的方法。但它看起来有点不稳定,我担心这在 1000 次尝试中有 1 次可能会出错。

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

There is only this awkward method fileExistsAtPath which also looks for files and not only directories. But for me, the dangerous thing is: What if this goes wrong? What shall I do? What is best practice to guarantee that the directory is created, and only created when it does not exist?

只有这个笨拙的方法 fileExistsAtPath 也查找文件而不仅仅是目录。但对我来说,危险的是:如果出现问题怎么办?我该怎么办?什么是保证目录被创建并且仅在它不存在时创建的最佳实践?

I know file system operations are never safe. Device could loose battery power suddenly just in the moment where it began shoveling the bits from A to B. Or it can stumble upon a bad bit and hang for a second. Maybe in some seldom cases it returns YES even if there is no directory. Simply put: I don't trust file system operations.

我知道文件系统操作从来都不是安全的。设备可能会在开始将碎片从 A 铲到 B 的那一刻突然失去电池电量。或者它可能会偶然发现一个坏碎片并挂起一秒钟。也许在极少数情况下,即使没有目录,它也会返回 YES。简单地说:我不信任文件系统操作。

How can I make this absolutely safe?

我怎样才能做到这一点绝对安全?

回答by e.James

You can actually skip the if, even though Apple's docs say that the directory must notexist, that is only true if you are passing withIntermediateDirectories:NO

您实际上可以跳过if,即使 Apple 的文档说该目录必须不存在,但只有在您通过时才如此withIntermediateDirectories:NO

That puts it down to one call. The next step is to capture any errors:

这归结为一个电话。下一步是捕获任何错误:

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

This will notresult in an error if the directory already exists.

如果目录已经存在,这不会导致错误。

回答by Sergey Nikitin

For Swift 3.0

对于 Swift 3.0

do {
    try FileManager.default.createDirectory(atPath: folder, withIntermediateDirectories: true, attributes: nil)
} catch {
    print(error)
}

回答by Abhishek Jain

Swift 4.2

斯威夫特 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)")
}

回答by Charles Burns

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

From an SO topic here.

来自此处的 SO 主题。

After creating a directory, you can flush the file system then check to see if your newly created directory exists. This is probably overkill, but you can never have too much overkill.

创建目录后,您可以刷新文件系统,然后检查新创建的目录是否存在。这可能是矫枉过正,但你永远不会有太多矫枉过正。

回答by Chris

In swift 2 it looks like this:

在 swift 2 中,它看起来像这样:

do {
    try NSFileManager.defaultManager().createDirectoryAtPath(pathURL.absoluteString, withIntermediateDirectories: true, attributes: nil)
} catch {
    print(error)
}