Wie überprüfe ich, ob eine Datei im Verzeichnis "Dokumente" in Swift vorhanden ist?

127

Wie überprüfe ich, ob eine Datei im Dokumentverzeichnis in vorhanden ist Swift?

Ich verwende die [ .writeFilePath ]Methode, um ein Bild im Verzeichnis "Dokumente" zu speichern, und möchte es bei jedem Start der App laden. Aber ich habe ein Standardbild, wenn es kein gespeichertes Bild gibt.

Aber ich kann mir nicht vorstellen, wie man die [ func fileExistsAtPath(_:) ]Funktion benutzt. Könnte jemand ein Beispiel für die Verwendung der Funktion mit einem übergebenen Pfadargument geben.

Ich glaube, ich muss dort keinen Code einfügen, da dies eine allgemeine Frage ist. Jede Hilfe wird sehr geschätzt.

Prost

GgnDpSingh
quelle

Antworten:

248

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, muss URLByAppendingPathComponent verwenden

    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")
    }
mike.tihonchik
quelle
Es sieht so aus, als ob die Antwort aktualisiert wurde, sodass die Kommentare von absoluteString veraltet zu sein scheinen.
Efren
Vermutlich waren diese Kommentare, dass absoluteString nicht über eine URL funktioniert, aber der Pfad, was ich gefunden habe!
CMash
33

Überprüfen Sie den folgenden Code:

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");
}
PREMKUMAR
quelle
3
@SaqibOmer versuchen Sie, Pfade als NSString anstatt als String umzuwandeln. var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
Schafgarbe
@PREMKUMAR Warum diese seltsame String-Interpolation? Sie könnten absoluteStringzum Konvertieren NSURLin verwenden, pathaber es wäre besser, den Pfad einfach als Zeichenfolge ( NSString) beizubehalten, wie Sie es in Swift 1.2 tun.
Sulthan
Ich fand diese Antwort richtig mit Swift 2 zu arbeiten: stackoverflow.com/a/36897617/1245231
petrsyn
27

Heute (2016) empfiehlt Apple mehr und mehr die URL verwandte API von zu verwenden NSURL, NSFileManagerusw.

Verwenden Sie zum Abrufen des Dokumentenverzeichnisses in iOS und Swift 2

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

Das try!ist in diesem Fall sicher, da dieses Standardverzeichnis garantiert existiert.

Fügen Sie dann die entsprechende Pfadkomponente hinzu, z. B. eine sqliteDatei

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

Überprüfen Sie nun, ob die Datei mit checkResourceIsReachableAndReturnErrorvon existiert NSURL.

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

Wenn Sie den Fehler benötigen, übergeben Sie den NSErrorZeiger auf den Parameter.

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

Swift 3+:

let documentDirectoryURL = try! FileManager.default.url(for: .documentDirectory, 
                                in: .userDomainMask, 
                    appropriateFor: nil, 
                            create: true)

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

checkResourceIsReachableist markiert als werfen kann

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

Verwenden Sie den Operator nil-coalescing, um nur den booleschen Rückgabewert zu berücksichtigen und den Fehler zu ignorieren

let fileExists = (try? databaseURL.checkResourceIsReachable()) ?? false
vadian
quelle
Ich denke in Swift 3 ist dies jetzt checkResourceIsReachable()und kehrt nur Boolfür URLTyp zurück.
Ethan Allen
1
Das Problem, das ich gefunden habe, ist, dass Sie in Swift3 scheinbar nie einen "falschen" Wert von checkResourceIsReachable () erhalten, nur eine Ausnahme, wenn die Datei nicht vorhanden ist. Ich bin nicht sehr glücklich mit einer API, bei der viele Aufrufe zu einer Ausnahme anstelle eines einfachen Rückgabewerts führen.
Kendall Helmstetter Gelner
@KendallHelmstetterGelner Swifts try - catchMuster löst keine Ausnahmen aus. Es ist nicht vergleichbar mit Ausnahmen in Objective-C. Es ist ein effizientes Fehlerbehandlungssystem.
Vadian
1
Ich weiß, es ist effizienter, aber konzeptionell mag ich es nicht. Es macht mir nichts aus, wenn eine Ausnahme ausgelöst wird - eine Ausnahme. Eine nicht vorhandene Datei ist jedoch KEINE Ausnahme. Dies ist ein häufiger Fall und sollte zu einem falschen Rückgabewert führen, nicht zu einer Aberration mit einem umschlossenen Fehlerobjekt, das erstellt werden musste. Es scheint nicht viel zu sein, aber wenn Sie Zehntausende von Dateien haben, um zu überprüfen, ob die Belastung zu hoch ist.
Kendall Helmstetter Gelner
16

Es ist ziemlich benutzerfreundlich. Arbeiten Sie einfach mit dem defaultManager-Singleton von NSFileManager und verwenden Sie dann die fileExistsAtPath()Methode, die einfach eine Zeichenfolge als Argument verwendet und einen Bool zurückgibt, sodass dieser direkt in die if-Anweisung eingefügt werden kann .

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!!
}

Beachten Sie, dass der Downcast zu String in Swift 2 nicht erforderlich ist.

Mick MacCallum
quelle
♦ Bitte helfen Sie mir hier stackoverflow.com/questions/31503283/… . Ich weiß nicht, welchen Code ich schreiben muss.
Alexander Khitev
6

Ein alternatives / empfohlenes Codemuster in Swift 3 wäre:

  1. Verwenden Sie URL anstelle von FileManager
  2. Verwendung der Ausnahmebehandlung

    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)")
        }
    }
Surya Kameswara Rao Ravi
quelle
5

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;
        }
    }
}

Verwenden von: -

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

Für Swift 3- Anfänger:

  1. Swift 3 hat den größten Teil der NextStep-Syntax abgeschafft
  2. Daher werden NSURL, NSFilemanager und NSSearchPathForDirectoriesInDomain nicht mehr verwendet
  3. Verwenden Sie stattdessen URL und FileManager
  4. NSSearchPathForDirectoriesInDomain wird nicht benötigt
  5. Verwenden Sie stattdessen FileManager.default.urls

Hier ist ein Codebeispiel, um zu überprüfen, ob eine Datei mit dem Namen "database.sqlite" im Verzeichnis des Anwendungsdokuments vorhanden ist:

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

}
Surya Kameswara Rao Ravi
quelle
3

Sehr einfach: Wenn Ihr Pfad eine URL-Instanz ist, konvertieren Sie sie mit der Methode 'path' in einen String.

    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
        }
    }
Rohit Sisodia
quelle
1

Das funktioniert gut für mich in 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

        }


}

Sie können mit diesem Anruf überprüfen:

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

            // your code if file exists

           } else {

           // your code if file does not exist

           }

Ich hoffe es ist nützlich für jemanden. @; -]

Maurizio FIORINO
quelle
Was ist, wenn der Benutzer nicht nur das Dokumentverzeichnis überprüfen möchte? und möchten einen generischen Pfad suchen
Jogendra Kumar
0

Sie müssen vor dem Dateinamen einen Schrägstrich "/" einfügen, sonst erhalten Sie einen Pfad wie "... / DocumentsFilename.jpg".

Jauzee
quelle
0

Swift 4 Beispiel:

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

Ich habe die Prüfung in meine loadData-Funktion eingefügt, die ich in viewDidLoad aufgerufen habe.

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

Dann habe ich unten loadData definiert.

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...")
    }
}
Joshua Dance
quelle
0

arbeitet bei Swift 5

    do {
        let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileUrl = documentDirectory.appendingPathComponent("userInfo").appendingPathExtension("sqlite3")
        if FileManager.default.fileExists(atPath: fileUrl.path) {
            print("FILE AVAILABLE")
        } else {
            print("FILE NOT AVAILABLE")
        }
    } catch {
        print(error)
    }

Dabei werden "userInfo"- Dateiname und "sqlite3"- Dateierweiterung

Nastassie
quelle