Bagaimana cara memeriksa apakah ada file di direktori Documents di Swift?


127

Bagaimana cara memeriksa apakah ada file di direktori Documents Swift?

Saya menggunakan [ .writeFilePath ]metode untuk menyimpan gambar ke direktori Documents dan saya ingin memuatnya setiap kali aplikasi diluncurkan. Tetapi saya memiliki gambar default jika tidak ada gambar yang disimpan.

Tapi saya tidak bisa mengerti bagaimana cara menggunakan [ func fileExistsAtPath(_:) ]fungsi ini. Bisakah seseorang memberi contoh menggunakan fungsi dengan argumen jalur diteruskan ke dalamnya.

Saya yakin saya tidak perlu menempelkan kode apa pun di sana karena ini adalah pertanyaan umum. Bantuan apa pun akan sangat dihargai.

Bersulang

Jawaban:


248

Versi Swift 4.x

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

Versi 3.x cepat

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

Versi Swift 2.x , perlu menggunakan 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")
    }

Sepertinya jawabannya telah diperbarui sehingga komentar absoluteString tampaknya usang.
Efren

mungkin komentar-komentar itu adalah absoluteString tidak berfungsi dari URL, tetapi path tidak, yang saya temukan!
CMash

33

Periksa kode di bawah ini:

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

3
@ SaqibOmer mencoba casting jalur sebagai NSString daripada String. var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
sheepgobeep

@ PREMKUMAR Mengapa interpolasi string aneh itu? Anda dapat menggunakan absoluteStringuntuk mengonversi NSURLke pathtetapi akan lebih baik untuk tetap menyimpan path sebagai string ( NSString) seperti yang Anda lakukan di Swift 1.2.
Sulthan

Saya menemukan jawaban ini berfungsi dengan baik dengan Swift 2: stackoverflow.com/a/36897617/1245231
petrsyn

27

Saat ini (2016) Apple merekomendasikan semakin banyak untuk menggunakan API terkait URL NSURL, NSFileManagerdll.

Untuk mendapatkan direktori dokumen di iOS dan Swift 2 gunakan

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

The try!aman dalam kasus ini karena direktori standar ini dijamin ada.

Kemudian tambahkan komponen path yang sesuai misalnya sqlitefile

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

Sekarang memeriksa apakah file ada dengan checkResourceIsReachableAndReturnErrordari NSURL.

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

Jika Anda memerlukan kesalahan, berikan NSErrorpointer ke 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")

checkResourceIsReachableditandai sebagai dapat melempar

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

Untuk mempertimbangkan hanya nilai pengembalian boolean dan mengabaikan kesalahan gunakan operator nil-penggabungan

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

Saya pikir di Swift 3 ini sekarang checkResourceIsReachable()dan hanya mengembalikan Booluntuk URLtipe.
Ethan Allen

1
Masalah yang saya temukan adalah bahwa Anda sepertinya tidak pernah mendapatkan nilai "false" dari checkResourceIsReachable () di Swift3, hanya pengecualian jika file tersebut tidak ada. Saya tidak terlalu senang menggunakan API di mana banyak panggilan akan menghasilkan pengecualian, bukan nilai balik yang sederhana.
Kendall Helmstetter Gelner

Pola @KendallHelmstetterGelner Swift try - catchtidak memberikan pengecualian. Itu tidak bisa dibandingkan dengan pengecualian di Objective-C. Ini adalah sistem penanganan kesalahan yang efisien.
vadian

1
Ini lebih efisien saya tahu, tetapi secara konseptual saya tidak menyukainya. Saya tidak keberatan melontarkan pengecualian untuk - pengecualian. Tetapi file yang tidak ada BUKAN pengecualian. Ini adalah kasus umum dan harus menghasilkan nilai pengembalian salah, bukan semacam penyimpangan dengan objek Galat terbungkus yang harus dibuat. Ini mungkin tidak tampak banyak tetapi jika Anda memiliki puluhan ribu file untuk memeriksa bebannya terlalu tinggi.
Kendall Helmstetter Gelner

16

Sangat user friendly. Hanya bekerja dengan singel defaultManager NSFileManager dan kemudian gunakan fileExistsAtPath()metode, yang hanya mengambil string sebagai argumen, dan mengembalikan Bool, yang memungkinkan untuk ditempatkan langsung dalam pernyataan 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!!
}

Perhatikan bahwa downcast to String tidak diperlukan di Swift 2.


♦ tolong bantu saya di sini stackoverflow.com/questions/31503283/… . Saya tidak tahu kode mana yang perlu ditulis.
Alexander Khitev

6

Pola Kode alternatif / yang disarankan dalam Swift 3 adalah:

  1. Gunakan URL alih-alih FileManager
  2. Penggunaan penanganan pengecualian

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

5

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

Menggunakan: -

if fileUrl.checkFileExist()
   {
      // Do Something
   }

4

Untuk kepentingan pemula Swift 3 :

  1. Swift 3 telah menghilangkan sebagian besar sintaks NextStep
  2. Jadi NSURL, NSFilemanager, NSSearchPathForDirectoriesInDomain tidak lagi digunakan
  3. Alih-alih menggunakan URL dan FileManager
  4. NSSearchPathForDirectoriesInDomain tidak diperlukan
  5. Alih-alih menggunakan FileManager.default.urls

Berikut adalah contoh kode untuk memverifikasi apakah file bernama "database.sqlite" ada di direktori dokumen aplikasi:

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

}

3

Sangat sederhana: Jika path Anda adalah instance URL, konversi ke string dengan metode '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
        }
    }

1

Ini berfungsi dengan baik untuk saya di 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

        }


}

Anda dapat memeriksa dengan panggilan ini:

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

            // your code if file exists

           } else {

           // your code if file does not exist

           }

Semoga bermanfaat bagi seseorang. @; -]


Bagaimana jika pengguna tidak ingin hanya memeriksa direktori dokumen? dan ingin mencari jalur umum
Jogendra Kumar

0

Anda harus menambahkan slash "/" sebelum nama file, atau Anda mendapatkan path seperti "... / DocumentsFilename.jpg"


0

Contoh Swift 4 :

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

Saya meletakkan cek di fungsi loadData yang saya panggil di viewDidLoad.

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

Lalu saya mendefinisikan loadData di bawah ini.

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

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

di mana "userInfo"- nama file, dan "sqlite3"- ekstensi file

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.