web-dev-qa-db-fra.com

Test de l'existence d'un fichier à l'aide de NSURL

Snow Leopard a introduit de nombreuses nouvelles méthodes d'utilisation des objets NSURL pour faire référence à des fichiers, et non à des noms de chemin d'accès ou aux FSRefs de Core Services.

Cependant, il y a une tâche pour laquelle je ne trouve pas de méthode basée sur l'URL: Tester si un fichier existe. Je recherche une version de - [NSFileManager fileExistsAtPath:] basée sur l'URL. Comme cette méthode, elle devrait renvoyer YES si l'URL décrit quoi que ce soit, qu'il s'agisse d'un fichier normal, d'un répertoire ou de quelque chose d'autre.

Je pourrais essayer de rechercher diverses valeurs de resource , mais aucune d'entre elles n'est explicitement garantie de ne pas exister si le fichier n'existe pas, et certaines d'entre elles (par exemple, NSURLEffectiveIconKey ) pourraient être onéreuses si .

Je pourrais simplement utiliser le fileExistsAtPath: de NSFileManager, mais s'il existe une méthode plus moderne, je préférerais l'utiliser.

Existe-t-il une méthode ou une fonction simple dans Cocoa, CF ou Core Services garantie/documentée pour me dire si une URL de fichier (ou de référence de fichier) donnée fait référence à un objet de système de fichiers existant?

70
Peter Hosey

NSURL a cette méthode:

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

Quelle "Renvoie si la ressource pointée par une URL de fichier peut être atteinte".

NSURL *theURL = [NSURL fileURLWithPath:@"/Users/elisevanlooij/nonexistingfile.php" 
               isDirectory:NO];
NSError *err;
if ([theURL checkResourceIsReachableAndReturnError:&err] == NO)
    [[NSAlert alertWithError:err] runModal];
136
Elise van Looij

Sur iOS, je ne pouvais pas trouver d'autre moyen ...

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

Voici la Swift 2 réponse:

var error:NSError?
let folderExists = theURL.checkResourceIsReachableAndReturnError(&error)
10
William Entriken

Déterminer si une URL de fichier (ou de référence de fichier) donnée fait référence à un objet de système de fichiers existant est intrinsèquement coûteux pour les ressources distantes. Même si vous les utilisiez, pour beaucoup de fichiers, vous seriez toujours confrontés à une surcharge de temps considérable.

Ce que vous devez faire est d’implémenter votre propre routine de contrôle asynchrone avec une mise en cache qui crée séparément une liste de ressources valides.

Sinon, les notes pour CFURLResourceIsReachable dans l'état de l'en-tête:

Un exemple serait la maintenance périodique de l'état de l'interface utilisateur qui dépend sur l'existence d'un document particulier. Lors de l'exécution d'un opération telle que l’ouverture d’un fichier, il est plus efficace d’essayer simplement le fichier opération et gérer les échecs que de vérifier d'abord pour l'accessibilité.

2
valexa

Comme NSURL peut représenter davantage que des systèmes de fichiers locaux, je ne pense pas qu’il existe une méthode générique permettant de vérifier leur existence de manière fiable. Au moins, la fondation Cocoa ne contient pas une telle fonction (à ma connaissance).

Si vous ne travaillez qu'avec des systèmes de fichiers locaux, je vous suggère de créer une catégorie pour NSURL ou pour NSFileManager, avec un message urlExists:. Il convertira la NSURL en une NSString (chemin normalisé), puis invoquera le message [NSFileManager fileExistsAtPath:].

1
Laurent Etiemble

Dans Swift, vous pouvez utiliser la méthode checkResourceIsReachable() qui, malheureusement, retournera true (si le fichier est accessible) ou renvoie une erreur (expliquant pourquoi il est impossible de l'atteindre).

Pour obtenir une valeur bool true/false, utilisez la syntaxe suivante:

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

Si vous souhaitez enregistrer l'erreur:

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

N'oubliez pas qu'il s'agit d'une opération coûteuse et qu'elle peut être obsolète immédiatement après (si un autre processus supprime un fichier ou démonte un fichier sur disque pendant que vous vérifiez s'il existe).

En général, l’approche privilégiée n’est pas de vérifier l’existence d’un fichier, mais simplement d’essayer de lire ou d’écrire dans un fichier et de gérer toute erreur par la suite, si elle échoue.

0
Abhi Beckert