47 votes

Swift 3.0 FileManager.fileExists(atPath :) toujours retourner false

Quand j'utilise la méthode .fileExists(atPath:) pour juger 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 bien. 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.

0 votes

Pointez-vous vers l'emplacement exact où le fichier existe ?

2 votes

Quelle est la valeur de filePath ? Commence-t-elle par ~ ? Si oui, vous devez d'abord appeler expandingTildeInPath

0 votes

@user3608500 Oui, pointe vers un fichier exact, je veux juger que ce fichier existe.

83voto

nayem Points 3140

Je suppose que votre url est un URL type. Si c'est le cas, 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 disant cela, 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 existe un moyen encore plus efficace, que l'on peut appeler le swift-way (:D). Vous n'avez pas à vérifier explicitement la présence de existence d'un 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)

Mise à jour pour Swift 3.0+ sans l'option Objective-C ish NS préfixe :

do {
    let result = try Data(contentsOf: fileURL)
    print(result)
} catch {
    print(error)
}

48 votes

SUPER ! Dans mon cas, j'utilisais .absoluteString au lieu de .path . Cela a réglé le problème

2 votes

L'utilisation de .path était la clé pour moi, au lieu de .absoluteString.

35voto

Martian2049 Points 781

Sur 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")
}

cette impression

/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é ?

0 votes

Honnêtement, si je pouvais revenir en arrière, j'aurais appris le CO à la place. Le swift n'est pas une langue courante.

2 votes

En soulignant que file:// a été coupé était essentiel. Merci beaucoup.

25voto

Martin Points 61

Je veux partager mon expérience, au cas où quelqu'un d'autre serait dérouté par ce problème.

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

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


Pour une application iOS, je sauvegardais une image dans .../Documents/Photos par le biais de l'URL relative, disons url . Lors de l'enregistrement de l'image, un chemin, par exemple url.path a également été sauvegardé dans une entité Core Data.

Quand j'ai ensuite essayé de récupérer l'image par FileManager.default.fileExists(atPath: url.path) il renvoie toujours false.

Je testais l'application sur mon iPhone. Il s'est avéré que, pour une raison quelconque, chaque fois que j'ai lancé l'application à partir de Xcode, le dossier d'identification de l'application a changé !

Donc :

  • Application ouverte depuis Xcode -> Image sauvegardée -> application fermée -> application ouverte depuis le dispositif physique -> fileExists -> VRAI
  • Application ouverte depuis Xcode -> Image sauvegardée -> application fermée -> application ouverte depuis Xcode -> fileExists -> FALSE

Vous pouvez vérifier si c'est votre cas en obtenant et en imprimant le chemin du dossier du document (ou l'URL, peu importe) et en le comparant avec le chemin (ou l'URL) enregistré. Si vous obtenez quelque chose comme ceci :

  • /var/mobile/Containers/Data/Application/ 5D4632AE-C432-4D37-A3F7-ECD05716AD8A /Documents..
  • /var/mobile/Containers/Data/Application/ D09904C3-D80D-48EB-ACFB-1E42D878AFA4 /Documents..

vous avez trouvé le problème.

1 votes

C'était la bonne explication pour moi. Peut-être ajouter un code pour sauvegarder et récupérer les images pour les autres qui cherchent de l'aide.

4 votes

Cela a résolu mon problème. Ce qui peut être très déroutant, c'est lorsque vous téléchargez le conteneur et que vous voyez que le fichier est là.

0 votes

Cela devrait être la réponse acceptée ici. La plupart des autres réponses sont des doublons de stackoverflow.com/questions/34135305/

0voto

Amogh Shettigar Points 85
 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

-1voto

Robert Avellar Points 1

J'ai eu le même problème, mais cela a fonctionné pour moi.

filePath.replacingOccurrences(of: "file://", with: "")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X