web-dev-qa-db-fra.com

Comment vérifier si un fichier existe dans le répertoire Documents de Swift?

Comment vérifier si un fichier existe dans le répertoire Documents dans Swift?

J'utilise la méthode [ .writeFilePath ] pour enregistrer une image dans le répertoire Documents et je souhaite la charger à chaque lancement de l'application. Mais j'ai une image par défaut s'il n'y a pas d'image enregistrée.

Mais je n'arrive pas à comprendre comment utiliser la fonction [ func fileExistsAtPath(_:) ]. Quelqu'un pourrait-il donner un exemple d'utilisation de la fonction avec un argument de chemin d'accès passé dans celle-ci?.

Je crois que je n'ai pas besoin de coller de code car c'est une question générique. Toute aide sera très appréciée.

À votre santé

102
GgnDpSingh

Swift 4.x version

    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let url = NSURL(fileURLWithPath: path)
    if let pathComponent = url.appendingPathComponent("nameOfFileHere") {
        let filePath = pathComponent.path
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: filePath) {
            print("FILE AVAILABLE")
        } else {
            print("FILE NOT AVAILABLE")
        }
    } else {
        print("FILE PATH NOT AVAILABLE")
    }

Swift 3.x version

    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let url = URL(fileURLWithPath: path)

    let filePath = url.appendingPathComponent("nameOfFileHere").path
    let fileManager = FileManager.default
    if fileManager.fileExists(atPath: filePath) {
        print("FILE AVAILABLE")
    } else {
        print("FILE NOT AVAILABLE")
    }

Swift 2.x version, besoin d'utiliser URLByAppendingPathComponent

    let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
    let url = NSURL(fileURLWithPath: path)
    let filePath = url.URLByAppendingPathComponent("nameOfFileHere").path!
    let fileManager = NSFileManager.defaultManager()
    if fileManager.fileExistsAtPath(filePath) {
        print("FILE AVAILABLE")
    } else {
        print("FILE NOT AVAILABLE")
    }
185
mike.tihonchik

Vérifiez le code ci-dessous:

Swift 1.2

let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String

let getImagePath = paths.stringByAppendingPathComponent("SavedFile.jpg")

let checkValidation = NSFileManager.defaultManager()

if (checkValidation.fileExistsAtPath(getImagePath))
{
    println("FILE AVAILABLE");
}
else
{
    println("FILE NOT AVAILABLE");
}

Swift 2.0

let paths = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let getImagePath = paths.URLByAppendingPathComponent("SavedFile.jpg")

let checkValidation = NSFileManager.defaultManager()

if (checkValidation.fileExistsAtPath("\(getImagePath)"))
{
    print("FILE AVAILABLE");
}
else
{
    print("FILE NOT AVAILABLE");
}
33
PREMKUMAR

De nos jours (2016), Apple recommande de plus en plus d'utiliser l'API liée à l'URL de NSURL, NSFileManager etc.

Pour obtenir le répertoire de documents sous iOS et Swift 2 utilisez

let documentDirectoryURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, 
                                 inDomain: .UserDomainMask, 
                        appropriateForURL: nil, 
                                   create: true)

Le try! est sans danger dans ce cas car il est garanti que ce répertoire standard existe.

Ajoutez ensuite le composant de chemin approprié, par exemple un fichier sqlite.

let databaseURL = documentDirectoryURL.URLByAppendingPathComponent("MyDataBase.sqlite")

Maintenant, vérifiez si le fichier existe avec checkResourceIsReachableAndReturnError sur NSURL.

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

Si vous avez besoin de l'erreur, transmettez le paramètre NSError au paramètre. 

var error : NSError?
let fileExists = databaseURL.checkResourceIsReachableAndReturnError(&error)
if !fileExists { print(error) }

Swift 3:

Dans Swift 3, checkResourceIsReachable est marqué comme peut lancer

do {
    let fileExists = try databaseURL.checkResourceIsReachable()
    // handle the boolean result
} catch let error as NSError {
    print(error)
}

Pour ne considérer que la valeur de retour booléenne et ignorer l'erreur, utilisez l'opérateur nil-coalescing

let fileExists = (try? databaseURL.checkResourceIsReachable()) ?? false
23
vadian

C'est assez convivial. Travaillez simplement avec le singleton defaultManager de NSFileManager, puis utilisez la méthode fileExistsAtPath(), qui prend simplement une chaîne en tant qu'argument et renvoie un booléen, ce qui permet de la placer directement dans l'instruction if.

let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectory = paths[0] as! String
let myFilePath = documentDirectory.stringByAppendingPathComponent("nameOfMyFile")

let manager = NSFileManager.defaultManager()
if (manager.fileExistsAtPath(myFilePath)) {
    // it's here!!
}

Notez que le downcast en String n'est pas nécessaire dans Swift 2.

14
Mick MacCallum

Un modèle de code alternatif/recommandé dans Swift 3 serait:

  1. Utiliser l'URL au lieu de FileManager
  2. Utilisation de la gestion des exceptions

    func verifyIfSqliteDBExists(){
        let docsDir     : URL       = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let dbPath      : URL       = docsDir.appendingPathComponent("database.sqlite")
    
        do{
            let sqliteExists : Bool = try dbPath.checkResourceIsReachable()
            print("An sqlite database exists at this path :: \(dbPath.path)")
    
        }catch{
            print("SQLite NOT Found at :: \(strDBPath)")
        }
    }
    

Pour le bénéfice de Swift 3 débutants:

  1. Swift 3 a supprimé la plupart de la syntaxe NeXTSTEP
  2. Donc, NSURL, NSFilemanager, NSSearchPathForDirectoriesInDomain ne sont plus utilisés
  3. Utilisez plutôt l'URL et FileManager 
  4. NSSearchPathForDirectoriesInDomain n'est pas nécessaire
  5. Utilisez plutôt FileManager.default.urls

Voici un exemple de code permettant de vérifier si un fichier nommé "database.sqlite" existe dans le répertoire du document d'application:

func findIfSqliteDBExists(){

    let docsDir     : URL       = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let dbPath      : URL       = docsDir.appendingPathComponent("database.sqlite")
    let strDBPath   : String    = dbPath.path
    let fileManager : FileManager   = FileManager.default

    if fileManager.fileExists(atPath:strDBPath){
        print("An sqlite database exists at this path :: \(strDBPath)")
    }else{
        print("SQLite NOT Found at :: \(strDBPath)")
    }

}

Très simple: Si votre chemin est une instance d'URL convertie en chaîne par la méthode 'path'.

    let fileManager = FileManager.default
    var isDir: ObjCBool = false
    if fileManager.fileExists(atPath: yourURLPath.path, isDirectory: &isDir) {
        if isDir.boolValue {
            //it's a Directory path
        }else{
            //it's a File path
        }
    }
2
Rohit Sisodia

Swift 4 exemple:

var filePath: String {
    //manager lets you examine contents of a files and folders in your app.
    let manager = FileManager.default

    //returns an array of urls from our documentDirectory and we take the first
    let url = manager.urls(for: .documentDirectory, in: .userDomainMask).first
    //print("this is the url path in the document directory \(String(describing: url))")

    //creates a new path component and creates a new file called "Data" where we store our data array
    return(url!.appendingPathComponent("Data").path)
}

Je mets la vérification dans ma fonction loadData que j'ai appelée dans viewDidLoad.

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

Ensuite, j'ai défini loadData ci-dessous.

func loadData() {
    let manager = FileManager.default

    if manager.fileExists(atPath: filePath) {
        print("The file exists!")

        //Do what you need with the file. 
        ourData = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as! Array<DataObject>         
    } else {
        print("The file DOES NOT exist! Mournful trumpets sound...")
    }
}
0
Joshua Dance

Cela fonctionne bien pour moi dans Swift4:

func existingFile(fileName: String) -> Bool {

    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let url = NSURL(fileURLWithPath: path)
    if let pathComponent = url.appendingPathComponent("\(fileName)") {
        let filePath = pathComponent.path
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: filePath) 

       {

        return true

        } else {

        return false

        }

    } else {

        return false

        }


}

Vous pouvez vérifier avec cet appel:

   if existingFile(fileName: "yourfilename") == true {

            // your code if file exists

           } else {

           // your code if file does not exist

           }

J'espère que c'est utile pour quelqu'un. @; -]

0
Maurizio FIORINO

Swift 4.2

extension URL    {
    func checkFileExist() -> Bool {
        let path = self.path
        if (FileManager.default.fileExists(atPath: path))   {
            print("FILE AVAILABLE")
            return true
        }else        {
            print("FILE NOT AVAILABLE")
            return false;
        }
    }
}

En utilisant: -

if fileUrl.checkFileExist()
   {
      // Do Something
   }
0
Lakhdeep Singh

Vous devez ajouter une barre oblique "/" avant le nom du fichier ou un chemin du type ".../DocumentsFilename.jpg"

0
Jauzee