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


Snow Leopard a introduit de nombreuses nouvelles méthodes pour utiliser des objets NSURL afin de faire référence à des fichiers, pas à des chemins d'accès ou aux FSRef de Core Services.

Cependant, il existe une tâche que je ne peux pas trouver une méthode basée sur une URL pour: tester si un fichier existe. Je cherche une version basée sur URL de - [NSFileManager fileExistsAtPath:]. Comme cette méthode, elle devrait revenir YES si l'URL décrit quelque chose, qu'il s'agisse d'un fichier normal, d'un répertoire ou de toute autre chose.

Je pourrais essayer de chercher divers valeurs de ressource, mais aucun d'entre eux n'est explicitement garanti pour ne pas exister si le fichier ne le fait pas, et certains d'entre eux (par exemple, NSURLEffectiveIconKey) pourrait être coûteux si c'est le cas.

Je pourrais juste utiliser les NSFileManager fileExistsAtPath:, 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 qui soit 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
2017-12-18 11:45


origine


Réponses:


NSURL a cette méthode:

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

Which "Indique 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];

135
2017-12-18 16:16



Sur iOS, je n'ai pas trouvé d'autre moyen ...

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

29
2018-01-20 10:38



Voici la Swift 2 répondre:

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

9
2018-01-28 20:11



Déterminer si une URL de fichier (ou de référence de fichier) donnée se rapporte à un objet système de fichier existant est intrinsèquement coûteux pour les ressources distantes, les api 10.6 seulement (pas d'iPhoneOS) pour ces CFURLResourceIsReachable () et [NSURL checkResourceIsReachableAndReturnError:] sont tous deux synchrones même si vous les utilisez, pour beaucoup de fichiers, vous attendez toujours un délai important.

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

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

Un exemple serait l'entretien 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   opération et gérer les pannes que de vérifier d'abord l'accessibilité.


2
2018-04-24 11:53



Puisque NSURL peut représenter plus que les systèmes de fichiers locaux, je ne pense pas qu'il existe une méthode générique capable de tester leur existence de manière fiable. Au moins, la fondation Cocoa ne contient pas une telle fonction (pour autant que je sache).

Si vous ne traitez que des systèmes de fichiers locaux, je vous suggère de créer une catégorie pour NSURL ou pour NSFileManager, avec un urlExists: message. Il convertirait le NSURL à un NSString (chemin normalisé), puis invoquer le [NSFileManager fileExistsAtPath:] message.


1
2017-12-18 12:06



En Swift, vous pouvez utiliser le checkResourceIsReachable() méthode, qui malheureusement retournera soit true (si le fichier est accessible) ou jette une erreur (en expliquant pourquoi il ne peut pas être atteint).

Pour obtenir une valeur bool true / false à la place, utilisez cette syntaxe:

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 périmée immédiatement après (si un autre processus supprime un fichier ou démonte un fichier de disque pendant que vous vérifiez s'il existe).

En général, l’approche privilégiée consiste à ne pas vérifier si un fichier existe, mais à essayer de lire ou d’écrire dans un fichier et de traiter toute erreur éventuelle en cas d’échec.


0
2018-06-25 03:23