【问题标题】:How to check if a file exists in Documents folder?如何检查文档文件夹中是否存在文件?
【发布时间】:2010-12-10 23:07:41
【问题描述】:

我有一个应用程序内购买,当用户购买东西时,将一个 html 文件下载到我的应用程序的 Documents 文件夹中。

现在我必须检查这个 HTML 文件是否存在,如果是,则加载这个 HTML 文件,否则加载我的默认 html 页面。

我该怎么做?使用NSFileManager,我无法离开mainBundle..

【问题讨论】:

  • “使用 NSFileManager 我无法脱离 mainBundle” - 你从哪里得到这条错误信息?

标签: ios iphone xcode webview nsfilemanager


【解决方案1】:

斯威夫特 3:

let documentsURL = try! FileManager().url(for: .documentDirectory,
                                          in: .userDomainMask,
                                          appropriateFor: nil,
                                          create: true)

... 为您提供文档目录的文件 URL。以下检查是否存在名为 foo.html 的文件:

let fooURL = documentsURL.appendingPathComponent("foo.html")
let fileExists = FileManager().fileExists(atPath: fooURL.path)

目标-C:

NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

NSString* foofile = [documentsPath stringByAppendingPathComponent:@"foo.html"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];

【讨论】:

  • 请注意,您是从应用程序的个人 Documents 目录中加载文件,而不是在越狱后找到的全局文件。如果您将应用程序安装在 /Applications 中,就好像它是一个主应用程序一样,您将可以访问整个文件系统,并且您将使用共享的 Documents 目录。如果您通过 iTunes 或 XCode 安装它,您将使用应用程序的个人目录。最好将文件存储在本地目录中以进行备份。
  • objectAtIndex:0 现在可以替换为 firstObject
  • 或者只是[0]通过索引访问
  • firstObject 比 [0] 和 objectAtIndex:0 更安全
  • @Itachi 实际上在这种情况下,我更喜欢数组中没有对象时的异常。如果firstObject 的结果是nil,那么程序将无法继续运行,因为Apple 框架中的某些内容已严重损坏。
【解决方案2】:

如果您以不同的方式设置文件系统或寻找设置文件系统的不同方式,然后检查文件是否存在于文档文件夹中,这是另一个示例。还显示动态检查

for (int i = 0; i < numberHere; ++i){
    NSFileManager* fileMgr = [NSFileManager defaultManager];
    NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString* imageName = [NSString stringWithFormat:@"image-%@.png", i];
    NSString* currentFile = [documentsDirectory stringByAppendingPathComponent:imageName];
    BOOL fileExists = [fileMgr fileExistsAtPath:currentFile];
    if (fileExists == NO){
        cout << "DOESNT Exist!" << endl;
    } else {
        cout << "DOES Exist!" << endl;
    }
}

【讨论】:

    【解决方案3】:

    Apple 建议不要依赖 fileExistAtPath: 方法。如果文件不存在,最好尝试打开文件并处理错误。

    NSFileManager 类参考

    注意:不建议尝试基于文件系统的当前状态或文件系统上的特定文件来判断行为。这样做可能会导致奇怪的行为或竞争条件。尝试操作(例如加载文件或创建目录)、检查错误并优雅地处理这些错误比尝试提前确定操作是否成功要好得多。有关文件系统竞争条件的详细信息,请参阅安全编码指南中的“竞争条件和安全文件操作”。

    来源:Apple Developer API Reference

    来自安全编码指南。

    为了防止这种情况,程序经常检查以确保目标目录中不存在具有特定名称的临时文件。如果存在这样的文件,则应用程序将其删除或为临时文件选择一个新名称以避免冲突。如果文件不存在,则应用程序打开文件进行写入,因为如果不存在文件,打开文件进行写入的系统例程会自动创建一个新文件。 攻击者通过持续运行创建具有适当名称的新临时文件的程序,可以(通过一点持久性和一些运气)在应用程序检查以确保临时文件不存在之间的间隙中创建文件当它打开它进行写作时。然后应用程序打开攻击者的文件并写入(请记住,系统例程会打开一个现有文件(如果有),并且仅在没有现有文件时创建一个新文件)。 攻击者的文件可能与应用程序的临时文件具有不同的访问权限,因此攻击者可以读取其中的内容。或者,攻击者可能已经打开了该文件。攻击者可以将文件替换为指向其他文件(攻击者拥有的文件或现有系统文件)的硬链接或符号链接。例如,攻击者可以将文件替换为系统密码文件的符号链接,从而在攻击后系统密码被破坏到包括系统管理员在内的任何人都无法登录的程度。

    【讨论】:

    • 虽然这是一个很好的答案,但它本身提供了很好的建议。很高兴看到如何通过一个小代码示例来实现这一点。
    【解决方案4】:

    检查文档/catchimage 路径中是否存在文件:

    NSString *stringPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
    NSString *tempName = [NSString stringWithFormat:@"%@/catchimage/%@.png",stringPath,@"file name"];
    NSLog(@"%@",temName);
    if([[NSFileManager defaultManager] fileExistsAtPath:temName]){
        // ur code here
    } else {
        // ur code here** 
    }
    

    【讨论】:

      【解决方案5】:

      Swift 2.0

      这是使用 Swift 检查文件是否存在的方法

      func isFileExistsInDirectory() -> Bool {
          let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
          let documentsDirectory: AnyObject = paths[0]
          let dataPath = documentsDirectory.stringByAppendingPathComponent("/YourFileName")
      
          return NSFileManager.defaultManager().fileExistsAtPath(dataPath)
      }
      

      【讨论】:

        【解决方案6】:
        NSArray *directoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        NSString *imagePath =  [directoryPath objectAtIndex:0];
        //If you have superate folder
        imagePath= [imagePath stringByAppendingPathComponent:@"ImagesFolder"];//Get docs dir path with folder name
        _imageName = [_imageName stringByAppendingString:@".jpg"];//Assign image name
        imagePath= [imagePath stringByAppendingPathComponent:_imageName];
        NSLog(@"%@", imagePath);
        
        //Method 1:
        BOOL file = [[NSFileManager defaultManager] fileExistsAtPath: imagePath];
        if (file == NO){
            NSLog("File not exist");
        } else {
            NSLog("File exist");
        }
        
        //Method 2:
        NSData *data = [NSData dataWithContentsOfFile:imagePath];
        UIImage *image = [UIImage imageWithData:data];
        if (!(image == nil)) {//Check image exist or not
            cell.photoImageView.image = image;//Display image
        }
        

        【讨论】:

          【解决方案7】:

          NSURL.h 提供了- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error 这样做

          NSURL *fileURL = [NSURL fileURLWithPath:NSHomeDirectory()];
          NSError * __autoreleasing error = nil;
          if ([fileURL checkResourceIsReachableAndReturnError:&error]) {
              NSLog(@"%@ exists", fileURL);
          } else {
              NSLog(@"%@ existence checking error: %@", fileURL, error);
          }
          

          或者使用 Swift

          if let url = URL(fileURLWithPath: NSHomeDirectory()) {
              do {
                  let result = try url.checkResourceIsReachable()
              } catch {
                  print(error)
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2018-12-26
            • 2011-11-15
            • 2016-06-11
            • 2012-02-05
            • 1970-01-01
            • 1970-01-01
            • 2013-03-12
            • 1970-01-01
            • 2011-10-09
            相关资源
            最近更新 更多