如何在Swift的Documents目录中检查文件是否存在?


127

如何检查文件目录中Swift是否存在文件?

我正在使用[ .writeFilePath ]将图像保存到Documents目录中的方法,并且每次启动应用程序时都想加载它。但是,如果没有保存的图像,我将使用默认图像。

但是我只是无法理解如何使用该[ func fileExistsAtPath(_:) ]功能。有人可以举一个使用传递路径参数的函数的例子。

我相信我不需要在其中粘贴任何代码,因为这是一个通用问题。任何帮助都感激不尽。

干杯

Answers:


248

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

大概这些评论是绝对字符串不能从URL工作,但是路径可以,这是我发现的!
CMash19年

33

检查以下代码:

斯威夫特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");
}

斯威夫特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)2016年

我发现此答案可与Swift 2一起正常使用:stackoverflow.com/a/36897617/1245231
petrsyn

27

如今(2016年),Apple建议越来越多的人使用与URL相关的API NSURLNSFileManager等等。

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

迅捷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

我认为在斯威夫特3这是现在checkResourceIsReachable(),只是回报BoolURL类型。
伊桑·艾伦

1
我发现的问题是,您似乎从未在Swift3中从checkResourceIsReachable()获得“假”值,如果文件不存在,这只是一个例外。我对使用API​​感到不满意,该API中的大量调用会导致异常而不是简单的返回值。
肯德尔·赫尔姆斯特·盖尔纳

@KendallHelmstetterGelner Swift的try - catch模式不会引发异常。它与Objective-C中的异常无法相比。这是一个高效的错误处理系统。
vadian

1
我知道它效率更高,但从概念上讲我不喜欢它。我不介意某些东西引发异常-异常。但是不存在的文件也不例外。这是一种常见情况,应该导致错误的返回值,而不是必须创建的包装好的Error对象的某种异常。看起来似乎不多,但是如果您有成千上万个文件来检查负担太重。
Kendall Helmstetter Gelner's

16

这是非常用户友好的。只需使用NSFileManager的defaultManager单例,然后使用该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中不需要向下转换为String。


♦请在这里stackoverflow.com/questions/31503283/…帮助我。我不知道需要编写哪些代码。
亚历山大·基特夫

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

斯威夫特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)
}

我将支票放入在viewDidLoad中调用的loadData函数中。

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"-文件扩展名

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.