Swift 3.0 FileManager.fileExists(atPath :)总是返回false

Dea*_*Lee 32 nsfilemanager ios swift

当我使用方法.fileExists(atPath:)来判断文件是否存在于文件系统中时,该方法总是向我返回false.我检查了文件系统,文件确实存在.这是我的代码:

let filePath = url?.path
var isDir : ObjCBool = false
if(self.fileManager.fileExists(atPath: filePath!, isDirectory: &isDir)){
     let result = NSData(contentsOfFile: filePath!)
}
Run Code Online (Sandbox Code Playgroud)

要么

let filePath = url?.path
if(self.fileManager.fileExists(atPath: filePath!)){
     let result = NSData(contentsOfFile: filePath!)
}
Run Code Online (Sandbox Code Playgroud)

始终会跳过if子句.

nay*_*yem 58

我认为你url是一个URL类型.如果是这样试试这个:

let filePath = url?.path  // always try to work with URL when accessing Files
if(FileManager.default.fileExists(atPath: filePath!)){  // just use String when you have to check for existence of your file
    let result = NSData(contentsOf: url!)  // use URL instead of String
}
Run Code Online (Sandbox Code Playgroud)

说得够,你应该像这样改变你的实现:

if(FileManager.default.fileExists(atPath: (url?.path)!)){  // just use String when you have to check for existence of your file
    let result = NSData(contentsOf: url!)  // use URL instead of String
}
Run Code Online (Sandbox Code Playgroud)

编辑:1

还有更好的方法,你可以称之为swift-way(:D).您不必显式检查文件是否存在.

guard let result = NSData(contentsOf: fileURL) else {
    // No data in your fileURL. So no data is received. Do your task if you got no data
    // Keep in mind that you don't have access to your result here.
    // You can return from here. 
    return
}
// You got your data successfully that was in your fileURL location. Do your task with your result.
// You can have access to your result variable here. You can do further with result constant.
print(result)
Run Code Online (Sandbox Code Playgroud)

  • 大!在我的情况下,我使用`.absoluteString`而不是`.path`.这解决了它 (31认同)
  • 使用 .path 是我的关键,而不是 .absoluteString。 (2认同)

Mar*_*049 25

swift 3 中,万一有人像我一样迷茫,这里是完整的片段:

let str = "file:///Users/martian2049/Library/Developer/CoreSimulator/Devices/67D744AA-6EEC-4AFD-A840-366F4D78A18C/data/Containers/Data/Application/DD96F423-AF9F-4F4D-B370-94ADE7D6D0A5/Documents/72b8b0fb-7f71-7f31-ac9b-f9cc95dfe90d.mp3"

let url = URL(string: str)
print(url!.path,"\n")

if FileManager.default.fileExists(atPath: url!.path) {
    print("FILE Yes AVAILABLE")
} else {
    print("FILE NOT AVAILABLE")
}
Run Code Online (Sandbox Code Playgroud)

这打印

/Users/martian2049/Library/Developer/CoreSimulator/Devices/67D744AA-6EEC-4AFD-A840-366F4D78A18C/data/Containers/Data/Application/DD96F423-AF9F-4F4D-B370-94ADE7D6D0A5/Documents/72b8b0fb-7f71-7f31-ac9b-f9cc95dfe90d.mp3 

FILE Yes AVAILABLE
Run Code Online (Sandbox Code Playgroud)

注意file://'被砍掉了怎么样?

  • 指出`file://` 被砍掉是必不可少的。太感谢了。 (2认同)

Mar*_*tin 11

我想分享我的经验,以防其他人对此感到困惑.

在iOS 10-11,Xcode 9.2和Swift 3.2上测试.

简短回答:如果将文件路径保存到磁盘,则可以通过不在其中包含Documents目录来解决. 相反,每次需要使用保存的路径检索文件时,请获取Documents目录并附加路径.


对于iOS应用程序,我正在通过相对URL将图像保存到.../Documents/Pictures,比如说url.保存图像后,一条路径url.path也可以保存在Core Data实体中.

当我后来尝试通过检索图像时FileManager.default.fileExists(atPath: url.path),它总是返回false.

我在iPhone上测试应用程序.事实证明,出于某种原因,每次我从Xcode运行应用程序时,应用程序标识符文件夹都会更改!!

所以:

  • 应用程序从Xcode打开 - >已保存图像 - >已关闭应用程序 - >从物理设备打开应用程序 - > fileExists - > TRUE
  • 应用程序从Xcode打开 - >图像保存 - >应用程序关闭 - >从Xcode打开的应用程序 - > fileExists - > FALSE

您可以通过获取并打印文档文件夹路径(或URL,无关紧要)并将其与保存的路径(或URL)进行比较来检查是否是您的情况.如果你得到这样的东西:

  • / var/mobile/Containers/Data/Application/5D4632AE-C432-4D37-A3F7-ECD05716AD8A/Documents ..
  • / var/mobile/Containers/Data/Application/D09904C3-D80D-48EB-ACFB-1E42D878AFA4/Documents ..

你发现了这个问题.

  • 这解决了我的问题。更令人困惑的是,当您下载容器并看到该文件在那里时。 (4认同)

Mal*_*oni 9

只需使用 path 而不是 absoluteString 来删除 file://

FileManager.default.fileExists(atPath: URL.init(string: "your_url")!.path)
Run Code Online (Sandbox Code Playgroud)


Amo*_*gar 0

 let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
    var path = paths[0] as String;
    path = path + "/YourFilePath"
    if((NSFileManager.defaultManager().fileExistsAtPath(path))) {
             let result = NSData(contentsOfFile: filePath!)}
Run Code Online (Sandbox Code Playgroud)

尝试上面的代码并再次检查