【问题标题】:Check if file exists at URL instead of path检查文件是否存在于 URL 而不是路径
【发布时间】:2011-12-14 07:07:11
【问题描述】:

如何检查文件是否存在于 URL(而不是路径)中,以便将预填充的默认存储设置到 iPhone 模拟器中:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Food.sqlite"];
/*
 Set up the store.
 For the sake of illustration, provide a pre-populated default store.
 */
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Food" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}

我已经读过,在最近的模板版本中,applicationDocumentsDirectory 方法返回一个 URL,因此我更改了代码以使用 NSURL 对象来表示文件路径。但是在[fileManager fileExistsAtPath:storePath],我需要将fileExistsAtPath 更改为fileExistsAtURL 之类的东西(显然它不存在)。

我检查了 NSFileManager 类参考,但没有找到适合我目的的合适任务。

有什么提示吗?

【问题讨论】:

    标签: objective-c nsfilemanager


    【解决方案1】:
    if (![fileManager fileExistsAtPath:[storeURL path]]) 
    ...
    

    来自documentation

    如果此 URL 对象包含文件 URL(由 isFileURL 确定), 该方法的返回值适合输入到 NSFileManager 或 NSPathUtilities。如果路径有一个斜杠 被剥离。

    【讨论】:

    • 使用[url absoluteString] 时出错。不要使用绝对字符串。干杯。
    • 谢谢你!!!! absoluteString 弄乱了我的文件。现在使用 .path 而不是 .absoluteString 一切都很好!
    • 应该的。商店 URL 只是不同,因为它不在应用程序沙箱中,而是在共享容器文件夹中。这个实现细节被抽象出来了,所以它应该可以工作。
    【解决方案2】:

    对于文件系统 URL NSURL 本身有一个方法来检查 URL 的可达性

    NSError *error;
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Food.sqlite"];
    if ([storeURL checkResourceIsReachableAndReturnError:&error]) {
      // do something
    } else {
      NSLog(@"%@", error);
    }
    

    【讨论】:

    • 最直接的解决方案。无需依赖fileManager。
    • 这在 Swift 领域有一个问题,如果项目不可访问, checkResourceIsReachable() 会抛出异常 (!)。所以你必须费尽心思去捕捉异常而不是检查返回结果......
    • @KendallHelmstetterGelner 实际上你没有。看我的回答here
    • 谢谢,我看了一下并发表了评论。我喜欢尝试的想法?包装器,但我真的不喜欢调用我知道主要会引发异常的东西,因为我不想要那种开销。
    • @KendallHelmstetterGelner Swift 异常没有比“if / then / else”更多的开销。这就是为什么它们必须在它们被抛出的相同范围内处理。它们实际上仍然只是返回码。请参阅swift book error handling section 中的“注意:” -> ... Swift 中的错误处理不涉及展开调用堆栈,这是一个计算成本很高的过程。因此, throw 语句的性能特征与 return 语句的性能特征相当。
    【解决方案3】:
    if (![fileManager fileExistsAtPath:[storeURL path]]) 
    

    没问题,但要小心: 对于像这样的网址:

    ..../Documents/1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50
    

    [storeURL path] 将为您提供该路径(它适用于 [storeURL lastPathComponent]

    ..../Documents/1158a3c96ca22c41b8e731b1d1af0e1e
    

    但是如果你在 /var/mobile/Applications/DB92F4DC-49E4-4B4A-8271-6A9DAE6963BC/Documents/1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50 这样的字符串上使用 lastPathComponent,它会给你1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50

    这很好,因为在 url 中,'?'用于GET参数,但如果与字符串混合,可能会遇到麻烦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多