Swiftのドキュメントディレクトリにファイルが存在するかどうかを確認する方法


127

ファイルがでDocumentsディレクトリに存在するかどうかを確認する方法Swift

[ .writeFilePath ]Documentsディレクトリに画像を保存する方法を使用していますが、アプリを起動するたびに画像をロードしたいと思います。しかし、保存された画像がない場合、デフォルトの画像があります。

しかし、私は[ func fileExistsAtPath(_:) ]関数の使い方を理解することができません。パス引数を渡された関数の使用例を誰かに教えてもらえますか?

これは一般的な質問なので、コードをそこに貼り付ける必要はありません。どんな助けでも大歓迎です。

乾杯

回答:


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コメントが古くなっているようです。
エフレン2017

おそらくそれらのコメントは、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としてキャストしてみてください。var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
sheepgobeep 2015

@PREMKUMARなぜその奇妙な文字列補間ですか?あなたは使用することができますabsoluteString変換することNSURLpathそれは(単なる文字列としてパスを維持する方が良いでしょうNSStringあなたはスウィフト1.2で行うように)。
スルタン

私はこの回答が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) }

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()ありBoolURL型のために戻ると思います。
イーサンアレン

1
私が見つけた問題は、Swift3のcheckResourceIsReachable()から「false」値を取得するようには見えないことです。ファイルがそこにない場合は例外です。単純な戻り値の代わりに多くの呼び出しが例外を発生させるAPIを使用するのはあまり満足できません。
Kendall Helmstetter Gelner 2017

@KendallHelmstetterGelner Swiftのtry - catchパターンは例外をスローしません。Objective-Cの例外とは比較できません。効率的なエラー処理システムです。
バディアン

1
私が知っている方が効率的ですが、概念的には好きではありません。例外をスローする何か-例外を気にしません。ただし、存在しないファイルも例外ではありません。これは一般的なケースであり、作成されなければならなかったラップされたErrorオブジェクトのある種の異常ではなく、偽の戻り値をもたらすはずです。それは多くのようには思えないかもしれませんが、チェックする数万のファイルがある場合、負担は高すぎます。
Kendall Helmstetter Gelner 2017

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

StringへのダウンキャストはSwift 2では必要ないことに注意してください。


♦こちらのstackoverflow.com/questions/31503283/…で私を助けてください。どのコードを書く必要があるのか​​わかりません。
Alexander Khitev 2015

6

Swift 3の代替/推奨コードパターンは次のようになります。

  1. FileManagerの代わりにURLを使用
  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

利益のためにスウィフト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インスタンスの場合、「パス」メソッドによって文字列に変換します。

    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"-ファイルの拡張子

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.