Swift'deki Belgeler dizininde bir dosya olup olmadığı nasıl kontrol edilir?


128

İçindeki Belgeler dizininde bir dosya olup olmadığı nasıl kontrol edilir Swift?

[ .writeFilePath ]Belgeler dizinine bir görüntü kaydetmek için yöntem kullanıyorum ve uygulama her başlatıldığında onu yüklemek istiyorum. Ancak kaydedilmiş bir resim yoksa varsayılan bir resmim var.

Ama bu [ func fileExistsAtPath(_:) ]işlevi nasıl kullanacağımı kafama takamıyorum . Birisi, işlevin kendisine iletilen bir yol argümanıyla kullanımına bir örnek verebilir mi?

Genel bir soru olduğu için oraya herhangi bir kod yapıştırmam gerekmediğine inanıyorum. Herhangi bir yardım çok takdir edilecektir.

Şerefe

Yanıtlar:


249

Swift 4.x sürümü

    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 sürümü

    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 sürümü, URLByAppendingPathComponent kullanmanız gerekir

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

Görünüşe göre cevap güncellenmiş, bu yüzden absoluteString yorumları eski görünüyor.
Efren

Muhtemelen bu yorumlar, absoluteString'in bir URL'den çalışmadığı, ancak yolun çalıştığı, bulduğum şeydi!
CMash

33

Aşağıdaki kodu kontrol edin:

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

3
@SaqibOmer, yolları String yerine NSString olarak yayınlamayı deneyin. var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
Sheepgobeep

@PREMKUMAR Neden bu garip dize enterpolasyonu? Biçimine absoluteStringdönüştürmek NSURLiçin kullanabilirsiniz , pathancak yolu NSStringSwift 1.2'de yaptığınız gibi bir dizge ( ) olarak tutmak daha iyi olacaktır .
Sulthan

Bu cevabı Swift 2 ile düzgün çalıştığını buldum: stackoverflow.com/a/36897617/1245231
petrsyn

27

Günümüzde (2016), Apple URL ilgili API kullanmak için daha çok önerir NSURL, NSFileManagervb

İOS ve Swift 2'de belgeler dizinini almak için şunu kullanın:

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

try!Bu standart dizininin olması garantilidir, çünkü bu durumda güvenlidir.

Ardından, örneğin bir sqlitedosya gibi uygun yol bileşenini ekleyin

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

Dosyanın varlığına Şimdi eğer kontrol checkResourceIsReachableAndReturnErrorarasında NSURL.

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

Hataya ihtiyacınız varsa, NSErrorişaretçiyi parametreye iletin.

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

checkResourceIsReachableatabilir olarak işaretlendi

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

Yalnızca boole dönüş değerini dikkate almak ve hatayı yok saymak için sıfır birleştirme operatörünü kullanın

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

Bence Swift 3'te bu şimdi checkResourceIsReachable()ve sadece yazı Booliçin geri dönüyor URL.
Ethan Allen

1
Bulduğum sorun, Swift3'te checkResourceIsReachable () 'dan hiçbir zaman "yanlış" bir değer almıyor gibi görünmenizdir, sadece dosya orada değilse bir istisna. Çok sayıda çağrının basit bir dönüş değeri yerine bir istisnayla sonuçlanacağı bir API kullanmaktan pek memnun değilim.
Kendall Helmstetter Gelner

@KendallHelmstetterGelner Swift'in try - catchkalıbı istisnalar atmaz. Objective-C'deki istisnalarla karşılaştırılamaz. Etkili bir hata işleme sistemidir.
vadian

1
Biliyorum daha verimli ama kavramsal olarak hoşuma gitmiyor. Bir istisna atan bir şeyi umursamıyorum - bir istisna. Ancak mevcut olmayan bir dosya bir istisna DEĞİLDİR. Bu yaygın bir durumdur ve yanlış bir dönüş değeriyle sonuçlanmalıdır, oluşturulması gereken sarmalanmış bir Error nesnesi ile bir tür sapma değil. Çok fazla görünmeyebilir, ancak kontrol etmek için on binlerce dosyanız varsa, yükü çok ağırdır.
Kendall Helmstetter Gelner

16

Oldukça kullanıcı dostudur. Sadece NSFileManager'ın defaultManager singletonuyla çalışın ve ardından fileExistsAtPath()basitçe bir dizgeyi argüman olarak alan ve bir Bool döndüren, doğrudan if ifadesine yerleştirilmesine izin veren yöntemi kullanın.

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

Swift 2'de String'e aşağı inmenin gerekli olmadığını unutmayın.


♦ lütfen bana yardım edin stackoverflow.com/questions/31503283/… . Hangi kodun yazılması gerektiğini bilmiyorum.
Alexander Khitev

6

Swift 3'te alternatif / önerilen Kod Modeli şöyle olacaktır:

  1. FileManager yerine URL kullanın
  2. İstisna işlemenin kullanımı

    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

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

Kullanarak: -

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

4

Swift 3'e yeni başlayanların yararı için :

  1. Swift 3, NextStep sözdiziminin çoğunu ortadan kaldırdı
  2. Dolayısıyla NSURL, NSFilemanager, NSSearchPathForDirectoriesInDomain artık kullanılmıyor
  3. Bunun yerine URL ve FileManager kullanın
  4. NSSearchPathForDirectoriesInDomain gerekli değildir
  5. Bunun yerine FileManager.default.urls kullanın

Burada, uygulama belge dizininde "database.sqlite" adlı bir dosyanın bulunup bulunmadığını doğrulamak için bir kod örneği verilmiştir:

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

Çok basit: Yolunuz bir URL örneğiyse, 'yol' yöntemiyle dizeye dönüştürün.

    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

Bu benim için swift4'te iyi çalışıyor:

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

        }


}

Bu aramayı kontrol edebilirsiniz:

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

            // your code if file exists

           } else {

           // your code if file does not exist

           }

Umarım birisi için yararlıdır. @; -]


Ya kullanıcı sadece belge dizinini kontrol etmek istemezse? ve genel bir yol aramak istiyor
Jogendra Kumar

0

Dosya adından önce bir "/" eğik çizgi eklemelisiniz, yoksa "... / DocumentsFilename.jpg" gibi bir yol alırsınız


0

Swift 4 örneği:

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

ViewDidLoad'da çağırdığım loadData işlevime denetimi koydum.

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

Sonra aşağıda loadData tanımladım.

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

Swift 5'te çalışıyor

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

nerede "userInfo"- dosyanın adı ve "sqlite3"- dosyanın uzantısı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.