web-dev-qa-db-fra.com

Swift 3.0 FileManager.fileExists (atPath :) renvoie toujours la valeur false

Lorsque j'utilise la méthode .fileExists(atPath:) pour déterminer si le fichier existe dans le système de fichiers, la méthode me renvoie toujours false. J'ai vérifié le système de fichiers et le fichier existe. Voici mon code:

let filePath = url?.path
var isDir : ObjCBool = false
if(self.fileManager.fileExists(atPath: filePath!, isDirectory: &isDir)){
     let result = NSData(contentsOfFile: filePath!)
}

ou

let filePath = url?.path
if(self.fileManager.fileExists(atPath: filePath!)){
     let result = NSData(contentsOfFile: filePath!)
}

la clause if sera toujours ignorée.

28
Dean Lee

Je suppose que votre url est un type URL. Si oui, essayez ceci:

let filePath = url?.path  // always try to work with URL when accessing Files
if(FileManager.default.fileExists(atPath: filePath!)){  // just use String when you have to check for existence of your file
    let result = NSData(contentsOf: url!)  // use URL instead of String
}

En dire assez, vous devriez changer votre implémentation comme ceci:

if(FileManager.default.fileExists(atPath: (url?.path)!)){  // just use String when you have to check for existence of your file
    let result = NSData(contentsOf: url!)  // use URL instead of String
}

EDIT: 1

Il y a encore mieux, vous pouvez l'appeler Swift-way (: D). Vous n'avez pas à vérifier explicitement l'existence de fichier .

guard let result = NSData(contentsOf: fileURL) else {
    // No data in your fileURL. So no data is received. Do your task if you got no data
    // Keep in mind that you don't have access to your result here.
    // You can return from here. 
    return
}
// You got your data successfully that was in your fileURL location. Do your task with your result.
// You can have access to your result variable here. You can do further with result constant.
print(result)
46
nayem

dans Swift 3 Juste au cas où quelqu'un serait confus comme moi, voici les extraits complets:

let str = "file:///Users/martian2049/Library/Developer/CoreSimulator/Devices/67D744AA-6EEC-4AFD-A840-366F4D78A18C/data/Containers/Data/Application/DD96F423-AF9F-4F4D-B370-94ADE7D6D0A5/Documents/72b8b0fb-7f71-7f31-ac9b-f9cc95dfe90d.mp3"

let url = URL(string: str)
print(url!.path,"\n")

if FileManager.default.fileExists(atPath: url!.path) {
    print("FILE Yes AVAILABLE")
} else {
    print("FILE NOT AVAILABLE")
}

cela imprime

/Users/martian2049/Library/Developer/CoreSimulator/Devices/67D744AA-6EEC-4AFD-A840-366F4D78A18C/data/Containers/Data/Application/DD96F423-AF9F-4F4D-B370-94ADE7D6D0A5/Documents/72b8b0fb-7f71-7f31-ac9b-f9cc95dfe90d.mp3 

FILE Yes AVAILABLE

remarquez comment le 'file://' a été coupé?

16
Martian2049

Je veux partager mon expérience, au cas où quelqu'un d'autre en serait dérouté. 

Testé sur iOS 10-11, Xcode 9.2 et Swift 3.2.

Réponse courte: si vous enregistrez un chemin de fichier sur un disque, vous pouvez résoudre le problème en n'incluant pas le répertoire Documents. .__ Au lieu de cela, chaque fois que vous devez récupérer le fichier avec le chemin enregistré, récupérez le répertoire Documents et ajoutez le chemin.


Pour une application iOS, j'enregistrais une image dans .../Documents/Images via l'URL relative, disons url. Lorsque l'image était enregistrée, un chemin d'accès, disons url.path, était également enregistré dans un fichier de données de base. entité.

Plus tard, lorsque j'ai essayé de récupérer l'image via FileManager.default.fileExists(atPath: url.path), elle renvoyait toujours la valeur false.

Je testais l'application sur mon iPhone. Il s'est avéré que, pour une raison quelconque, à chaque fois que j'exécutais l'application depuis Xcode, le dossier d'identifiant d'application était changé!

Alors: 

  • Application ouverte à partir de Xcode -> Image enregistrée -> Application fermée -> Application ouverte à partir d'un périphérique physique -> FileExists -> TRUE 
  • Application ouverte à partir de Xcode -> Image enregistrée -> Application fermée -> Application ouverte à partir de Xcode -> fileExists -> FALSE

Vous pouvez vérifier si tel est votre cas en récupérant et en imprimant le chemin du dossier du document (ou l'URL, peu importe) et en le comparant au chemin enregistré (ou à l'URL). Si vous obtenez quelque chose comme ça:

  • / var/mobile/Conteneurs/Données/Application / 5D4632AE-C432-4D37-A3F7-ECD05716AD8A / Documents ..
  • / var/mobile/Conteneurs/Données/Application / D09904C3-D80D-48EB-ACFB-1E42D878AFA4 / Documents ..

vous avez trouvé le problème.

5
Martin
 let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
    var path = paths[0] as String;
    path = path + "/YourFilePath"
    if((NSFileManager.defaultManager().fileExistsAtPath(path))) {
             let result = NSData(contentsOfFile: filePath!)}

Essayez le code ci-dessus et vérifiez à nouveau

0
Amogh Shettigar