Testing file existence using NSURL

五迷三道 提交于 2019-11-28 04:03:08

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

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

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"file.type"];
if ([[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {...}

Here is the Swift 2 answer:

var error:NSError?
let folderExists = theURL.checkResourceIsReachableAndReturnError(&error)
valexa

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!