web-dev-qa-db-ja.com

Swift 3.0 FileManager.fileExists(atPath :)は常にfalseを返します

メソッド.fileExists(atPath:)を使用してファイルがファイルシステムに存在するかどうかを判断すると、メソッドは常にfalseを返します。ファイルシステムをチェックしましたが、ファイルは存在します。ここに私のコードがあります:

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

または

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

if節は常にスキップされます。

30
Dean Lee

あなたのurlURL型であると思います。もしそうならこれを試してください:

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
}

十分に言えば、次のように実装を変更する必要があります。

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
}

編集: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)
56
nayem

in Swift私がやったように誰かが混乱した場合に備えて、ここに完全なスニペットがあります:

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

これは印刷します

/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

'file:// '切り刻まれた?

25
Martian2049

他の誰かがこれに困惑した場合に備えて、私の経験を共有したいと思います。

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 ..

問題が見つかりました。

9
Martin
 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!)}

上記のコードを試して、もう一度確認してください

0
Amogh Shettigar

私はこれが私のために働いた同じ問題を抱えていた

filePath.replacingOccurrences(of: "file://", with: "")
0
Robert Avellar