วิธีตรวจสอบว่ามีไฟล์อยู่ในไดเร็กทอรี Documents ใน Swift หรือไม่


128

จะตรวจสอบได้อย่างไรว่ามีไฟล์อยู่ในไดเร็กทอรี Documents ในSwift?

ฉันใช้[ .writeFilePath ]วิธีบันทึกภาพลงในไดเร็กทอรี Documents และต้องการโหลดทุกครั้งที่เปิดแอป แต่ฉันมีภาพเริ่มต้นหากไม่มีภาพที่บันทึกไว้

แต่ฉันไม่สามารถเข้าใจวิธีใช้[ func fileExistsAtPath(_:) ]ฟังก์ชันนี้ได้ ใครช่วยยกตัวอย่างการใช้ฟังก์ชันที่มีพา ธ อาร์กิวเมนต์ส่งเข้ามาได้

ฉันเชื่อว่าฉันไม่จำเป็นต้องวางโค้ดใด ๆ ลงไปในนั้นเนื่องจากเป็นคำถามทั่วไป ความช่วยเหลือใด ๆ จะได้รับการชื่นชมมาก

ไชโย

คำตอบ:


249

เวอร์ชัน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")
    }

เวอร์ชันSwift 3.x

    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จำเป็นต้องใช้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")
    }

ดูเหมือนว่าคำตอบจะได้รับการอัปเดตดังนั้นความคิดเห็น absoluteString จึงดูล้าสมัย
Efren

ความคิดเห็นเหล่านั้นน่าจะเป็นที่ absoluteString ไม่ทำงานจาก URL แต่เส้นทางทำซึ่งเป็นสิ่งที่ฉันพบ!
CMash

33

ตรวจสอบรหัสด้านล่าง:

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 ลองแคสต์พา ธ เป็น NSString แทน String var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
sheepgobeep

@PREMKUMAR ทำไมการแก้ไขสตริงแปลก ๆ ? คุณสามารถใช้absoluteStringเพื่อแปลงNSURLเป็นได้pathแต่จะดีกว่าถ้าเก็บพา ธ เป็นสตริง ( NSString) เหมือนที่คุณทำใน Swift 1.2
Sulthan

ฉันพบว่าคำตอบนี้ทำงานได้อย่างถูกต้องกับ Swift 2: stackoverflow.com/a/36897617/1245231
petrsyn

27

ปัจจุบัน (2016) Apple แนะนำให้ใช้ URL ที่เกี่ยวข้องกับ API ของ NSURL , NSFileManagerฯลฯ

เพื่อรับไดเร็กทอรีเอกสารใน iOS และSwift 2ใช้

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

try!มีความปลอดภัยในกรณีนี้เพราะไดเรกทอรีมาตรฐานนี้มีการประกันเพื่ออยู่

จากนั้นต่อท้ายองค์ประกอบเส้นทางที่เหมาะสมเช่นsqliteไฟล์

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

ขณะนี้ตรวจสอบว่าไฟล์ที่มีอยู่กับของcheckResourceIsReachableAndReturnErrorNSURL

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

หากคุณต้องการข้อผิดพลาดให้ส่งNSErrorตัวชี้ไปที่พารามิเตอร์

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

checkResourceIsReachableถูกทำเครื่องหมายว่าสามารถโยนได้

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

ในการพิจารณาเฉพาะค่าที่ส่งคืนบูลีนและละเว้นข้อผิดพลาดให้ใช้ตัวดำเนินการ nil-coalescing

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

ฉันคิดว่าใน Swift 3 นี่คือตอนนี้checkResourceIsReachable()และเพิ่งกลับมาBoolสำหรับURLประเภท
Ethan Allen

1
ปัญหาที่ฉันพบคือคุณไม่เคยได้รับค่า "เท็จ" จาก checkResourceIsReachable () ใน Swift3 เป็นเพียงข้อยกเว้นหากไม่มีไฟล์อยู่ ฉันไม่ค่อยพอใจกับการใช้ API ที่การโทรจำนวนมากจะส่งผลให้เกิดข้อยกเว้นแทนที่จะเป็นค่าส่งคืนธรรมดา
Kendall Helmstetter Gelner

try - catchรูปแบบของเจลเนอร์สวิฟต์ไม่ได้มีข้อยกเว้น เทียบไม่ได้กับข้อยกเว้นใน Objective-C เป็นระบบจัดการข้อผิดพลาดที่มีประสิทธิภาพ
vadian

1
ฉันรู้ว่ามีประสิทธิภาพมากกว่า แต่โดยแนวคิดแล้วฉันไม่ชอบ ฉันไม่รังเกียจบางสิ่งบางอย่างที่ทำให้เกิดข้อยกเว้น - ข้อยกเว้น แต่ไฟล์ที่ไม่มีอยู่ก็ไม่ใช่ข้อยกเว้น เป็นกรณีทั่วไปและควรส่งผลให้ค่าส่งคืนเป็นเท็จไม่ใช่ความผิดปกติบางอย่างกับอ็อบเจ็กต์ข้อผิดพลาดที่ถูกห่อซึ่งต้องถูกสร้างขึ้น อาจดูเหมือนไม่มาก แต่ถ้าคุณมีไฟล์เป็นหมื่นเพื่อตรวจสอบภาระนั้นสูงเกินไป
Kendall Helmstetter Gelner

16

เป็นมิตรกับผู้ใช้ เพียงแค่ทำงานกับ defaultManager singleton ของ NSFileManager จากนั้นใช้fileExistsAtPath()เมธอดซึ่งใช้สตริงเป็นอาร์กิวเมนต์และส่งคืน Bool เพื่อให้สามารถวางได้โดยตรงในคำสั่ง 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!!
}

โปรดทราบว่าการดาวน์แคสต์เป็นสตริงไม่จำเป็นใน Swift 2


♦โปรดช่วยฉันที่นี่stackoverflow.com/questions/31503283/… . ฉันไม่รู้ว่าต้องเขียนโค้ดไหน
Alexander Khitev

6

รูปแบบรหัสทางเลือก / ที่แนะนำในSwift 3จะเป็น:

  1. ใช้ URL แทน FileManager
  2. การใช้การจัดการข้อยกเว้น

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

ใช้: -

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

4

เพื่อประโยชน์ของผู้เริ่มต้นใช้งานSwift 3 :

  1. Swift 3 ได้ใช้ไวยากรณ์ NextStep เกือบทั้งหมดแล้ว
  2. ดังนั้น NSURL, NSFilemanager, NSSearchPathForDirectoriesInDomain จึงไม่ถูกใช้อีกต่อไป
  3. ใช้ URL และ FileManager แทน
  4. NSSearchPathForDirectoriesInDomain ไม่จำเป็น
  5. ใช้ FileManager.default.urls แทน

นี่คือตัวอย่างโค้ดเพื่อตรวจสอบว่าไฟล์ชื่อ "database.sqlite" มีอยู่ในไดเร็กทอรีเอกสารแอปพลิเคชันหรือไม่:

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

ง่ายมาก: หากเส้นทางของคุณเป็นอินสแตนซ์ URL ที่แปลงเป็นสตริงโดยวิธี '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

สิ่งนี้ใช้ได้ดีสำหรับฉันใน 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

        }


}

คุณสามารถตรวจสอบด้วยสายนี้:

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

            // your code if file exists

           } else {

           // your code if file does not exist

           }

ฉันหวังว่าจะเป็นประโยชน์สำหรับใครบางคน @ -]


จะเป็นอย่างไรหากผู้ใช้ไม่ต้องการเพียงตรวจสอบไดเรกทอรีเอกสาร และต้องการค้นหาเส้นทางทั่วไป
Jogendra Kumar

0

คุณต้องเพิ่มเครื่องหมายทับ "/" ก่อนชื่อไฟล์มิฉะนั้นคุณจะได้รับเส้นทางเช่น "... / DocumentsFilename.jpg"


0

ตัวอย่าง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)
}

ฉันใส่การตรวจสอบในฟังก์ชัน loadData ของฉันซึ่งฉันเรียกใน viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

จากนั้นฉันกำหนด loadData ด้านล่าง

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

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

โดยที่"userInfo"- ชื่อ"sqlite3"ไฟล์และ- นามสกุลของไฟล์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.