Testing file existence using NSURL

前端 未结 6 2061
失恋的感觉
失恋的感觉 2020-12-07 20:10

Snow Leopard introduced many new methods to use NSURL objects to refer to files, not pathnames or Core Services\' FSRefs.

However, there\'s one task I can\'t find a

相关标签:
6条回答
  • 2020-12-07 20:21

    In Swift you can use the checkResourceIsReachable() method, which unfortunately will either return true (if the file is reachable) or throw an error (explaining why it cannot be reached).

    To get a bool true/false value instead, use this syntax:

    let exists = (try? inputFile.checkResourceIsReachable()) ?? false
    

    If you'd like to log the error:

    let exists: Bool
    do {
      exists = try inputFile.checkResourceIsReachable()
    } catch {
      exists = false
      print(error.localizedDescription)
    }
    

    Keep in mind this is an expensive operation and it could be out of date immediately after (if some other process is deleting a or unmounts a disk file while you're checking if it exists).

    In general the preferred approach is not to check wether a file exists, instead simply attempt to read or write to a file and handle any error afterwards if it fails.

    0 讨论(0)
  • 2020-12-07 20:22

    Determining if a given file (or file-reference) URL refers to a file-system object that exists is inherently costly for remote resources, the 10.6 only (no iPhoneOS) api's for this CFURLResourceIsReachable() and [NSURL checkResourceIsReachableAndReturnError:] are both synchronous, even if you would be using them, for a lot of files you would still be looking at a significant delay overhead.

    What you should do is implement your own asynchronous checking routine with caching that separately creates a list of valid resources.

    Otherwise the notes for CFURLResourceIsReachable in the header state :

    An example would be periodic maintenance of UI state that depends on the existence of a particular document. When performing an operation such as opening a file, it is more efficient to simply try the operation and handle failures than to check first for reachability.

    0 讨论(0)
  • 2020-12-07 20:25

    Here is the Swift 2 answer:

    var error:NSError?
    let folderExists = theURL.checkResourceIsReachableAndReturnError(&error)
    
    0 讨论(0)
  • 2020-12-07 20:27

    NSURL does have this method:

    - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error
    

    Which "Returns whether the resource pointed to by a file URL can be reached."

    NSURL *theURL = [NSURL fileURLWithPath:@"/Users/elisevanlooij/nonexistingfile.php" 
                   isDirectory:NO];
    NSError *err;
    if ([theURL checkResourceIsReachableAndReturnError:&err] == NO)
        [[NSAlert alertWithError:err] runModal];
    
    0 讨论(0)
  • 2020-12-07 20:32

    On iOS I couldn't find any other way...

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"file.type"];
    if ([[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {...}
    
    0 讨论(0)
  • 2020-12-07 20:32

    Because NSURL can represents more that local file-systems, I don't think that there is a generic method that can test for their existence in a reliable way. At least, the Cocoa foundation does not contains such a function (as far as I know).

    If you only deal with local file-systems, I suggest you to create a category for NSURL or for NSFileManager, with a urlExists: message. It would convert the NSURL to a NSString (normalized path) and then invoke the [NSFileManager fileExistsAtPath:] message.

    0 讨论(0)
提交回复
热议问题