Làm cách nào để kiểm tra xem một tệp có tồn tại trong thư mục Documents trong Swift không?


127

Làm thế nào để kiểm tra nếu một tập tin tồn tại trong thư mục Documents trong Swift?

Tôi đang sử dụng [ .writeFilePath ]phương pháp để lưu hình ảnh vào thư mục Documents và tôi muốn tải nó mỗi khi ứng dụng được khởi chạy. Nhưng tôi có một hình ảnh mặc định nếu không có hình ảnh được lưu.

Nhưng tôi không thể hiểu được cách sử dụng [ func fileExistsAtPath(_:) ]chức năng này. Ai đó có thể đưa ra một ví dụ về việc sử dụng hàm với một đối số đường dẫn được truyền vào nó.

Tôi tin rằng tôi không cần phải dán bất kỳ mã nào vào đó vì đây là một câu hỏi chung chung. Bất kỳ trợ giúp sẽ được nhiều đánh giá cao.

Chúc mừng

Câu trả lời:


248

Phiên bản 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")
    }

Phiên bản 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")
    }

Phiên bản Swift 2.x , cần sử dụng 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")
    }

Có vẻ như câu trả lời đã được cập nhật để các bình luận perfectString có vẻ lỗi thời.
Efren

có lẽ những ý kiến ​​đó là perfectString không hoạt động từ một URL, nhưng đường dẫn thì đó là những gì tôi tìm thấy!
CMash

33

Kiểm tra mã dưới đây:

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 thử truyền các đường dẫn dưới dạng NSString chứ không phải String. var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
Sheepgobeep

@PREMKUMAR Tại sao phép nội suy chuỗi lạ đó? Bạn có thể sử dụng absoluteStringđể chuyển đổi NSURLsang pathnhưng sẽ tốt hơn nếu chỉ giữ đường dẫn dưới dạng một chuỗi ( NSString) như bạn làm trong Swift 1.2.
Sulthan

Tôi đã tìm thấy câu trả lời này để hoạt động chính xác với Swift 2: stackoverflow.com/a/36897617/1245231
petrsyn

27

Ngày nay (2016) Apple khuyến nghị ngày càng nhiều hơn để sử dụng API liên quan đến URL NSURL, NSFileManagerv.v.

Để lấy thư mục tài liệu trong iOS và Swift 2, hãy sử dụng

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

Điều try!này là an toàn trong trường hợp này bởi vì thư mục tiêu chuẩn này được đảm bảo tồn tại.

Sau đó nối thêm thành phần đường dẫn thích hợp, ví dụ một sqlitetệp

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

Bây giờ kiểm tra nếu tập tin tồn tại với checkResourceIsReachableAndReturnErrorcác NSURL.

let fileExists = databaseURL.checkResourceIsReachableAndReturnError(nil)

Nếu bạn cần lỗi, chuyển NSErrorcon trỏ đến tham số.

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được đánh dấu là có thể ném

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

Để chỉ xem xét giá trị trả về boolean và bỏ qua lỗi, hãy sử dụng toán tử hợp nhất nil

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

Tôi nghĩ rằng trong Swift 3 này bây giờ là checkResourceIsReachable()và chỉ trở lại Boolcho URLloại.
Ethan Allen

1
Vấn đề tôi tìm thấy là dường như bạn không bao giờ nhận được giá trị "sai" từ checkResourceIsReachable () trong Swift3, chỉ là một ngoại lệ nếu tệp không có ở đó. Tôi không hài lòng khi sử dụng API trong đó nhiều cuộc gọi sẽ dẫn đến ngoại lệ thay vì giá trị trả lại đơn giản.
Kendall Helmstetter Gelner

Mẫu của @KendallHelmstetterGelner Swift try - catchkhông có ngoại lệ. Nó không thể so sánh với các ngoại lệ trong Objective-C. Đây là một hệ thống xử lý lỗi hiệu quả.
vadian

1
Nó hiệu quả hơn tôi biết, nhưng về mặt khái niệm tôi không thích nó. Tôi không bận tâm điều gì đó ném một ngoại lệ cho - một ngoại lệ. Nhưng một tập tin không tồn tại KHÔNG phải là một ngoại lệ. Đây là trường hợp phổ biến và sẽ dẫn đến giá trị trả về sai, không phải là một loại quang sai với đối tượng Lỗi được bao bọc phải được tạo. Có vẻ như không nhiều nhưng nếu bạn có hàng chục ngàn tệp để kiểm tra thì gánh nặng quá cao.
Kendall Helmstetter Gelner

16

Nó khá thân thiện với người dùng. Chỉ cần làm việc với singleton defaultFager của NSFileManag rồi sử dụng fileExistsAtPath()phương thức, đơn giản chỉ lấy một chuỗi làm đối số và trả về Bool, cho phép đặt trực tiếp vào câu lệnh 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!!
}

Lưu ý rằng downcast to String không cần thiết trong Swift 2.


♦ hãy giúp tôi ở đây stackoverflow.com/questions/31503283/ . Tôi không biết mã nào cần viết.
Alexander Khitev 19/07/2015

6

Một mẫu mã thay thế / được đề xuất trong Swift 3 sẽ là:

  1. Sử dụng URL thay vì Trình quản lý tệp
  2. Sử dụng xử lý ngoại lệ

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

Sử dụng: -

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

4

Vì lợi ích của Swift 3 người mới bắt đầu:

  1. Swift 3 đã loại bỏ hầu hết cú pháp NextStep
  2. Vì vậy, NSURL, NSFilemanager, NSSearchPathForDirectoriesInDomain không còn được sử dụng
  3. Thay vào đó hãy sử dụng URL và Trình quản lý tệp
  4. Không cần NSSearchPathForDirectoriesInDomain
  5. Thay vào đó, hãy sử dụng FileManager.default.urls

Dưới đây là một mẫu mã để xác minh nếu một tệp có tên "database.sqlite" tồn tại trong thư mục tài liệu ứng dụng:

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

Rất đơn giản: Nếu đường dẫn của bạn là một thể hiện URL chuyển đổi thành chuỗi theo phương thức '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

Điều này hoạt động tốt với tôi trong 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

        }


}

Bạn có thể kiểm tra với cuộc gọi này:

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

            // your code if file exists

           } else {

           // your code if file does not exist

           }

Tôi hy vọng nó hữu ích cho một ai đó. @; -]


Điều gì xảy ra nếu người dùng không muốn chỉ kiểm tra thư mục tài liệu? và muốn tìm kiếm một con đường chung
Jogendra Kumar

0

Bạn phải thêm dấu gạch chéo "/" trước tên tệp hoặc bạn có đường dẫn như "... / DocumentsFilename.jpg"


0

Ví dụ 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)
}

Tôi đặt kiểm tra trong hàm loadData mà tôi đã gọi trong viewDidLoad.

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()
}

Sau đó, tôi xác định loadData bên dưới.

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

làm việc tại 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)
    }

trong đó "userInfo"- tên "sqlite3"tệp và - phần mở rộng của tệp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.