简体   繁体   English

无法将文件从捆绑包复制到iOS中的文档目录

[英]Can`t copy file from bundle to documents directory in iOS

I am trying to copy a file from my bundle to the documents directory in iOS with the following code. 我试图使用以下代码将我的包中的文件复制到iOS中的文档目录。

let bundlePath = NSBundle.mainBundle().pathForResource("information", ofType: ".png")
print(bundlePath, "\n") //prints the correct path
let destPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
let fileManager = NSFileManager.defaultManager()
let fullDestPath = NSURL(fileURLWithPath: destPath).URLByAppendingPathComponent("information.png")
let fullDestPathString = String(fullDestPath)
print(fileManager.fileExistsAtPath(bundlePath!)) // prints true

do{
try fileManager.copyItemAtPath(bundlePath!, toPath: fullDestPathString)
}catch{
    print("\n")
    print(error)
}

Error Domain=NSCocoaErrorDomain Code=4 "The file “information.png” doesn't exist." 错误域= NSCocoaErrorDomain代码= 4“文件”information.png“不存在。” UserInfo={NSSourceFilePathErrorKey=/Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Bundle/Application/EFA83E02-5F24-4BB3-B32A-7E755081A730/AutoLayout tuts.app/information.png, NSUserStringVariant=( Copy ), NSDestinationFilePath=file:///Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Data/Application/86A1BDD5-FAF2-486E-85A9-CF72A547C6CD/Documents/information.png, NSFilePath=/Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Bundle/Application/EFA83E02-5F24-4BB3-B32A-7E755081A730/AutoLayout tuts.app/information.png, NSUnderlyingError=0x7fb53251cd80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} UserInfo = {NSSourceFilePathErrorKey = / Users / macbookpro / Library / Developer / CoreSimulator / Devices / E58CA1C6-C6F1-4D72-9572-3925675E78A5 / data / Containers / Bundle / Application / EFA83E02-5F24-4BB3-B32A-7E755081A730 / AutoLayout tuts.app /information.png,NSUserStringVariant =(Copy),NSDestinationFilePath = file:/// Users / macbookpro / Library / Developer / CoreSimulator / Devices / E58CA1C6-C6F1-4D72-9572-3925675E78A5 / data / Containers / Data / Application / 86A1BDD5- FAF2-486E-85A9-CF72A547C6CD / Documents / information.png,NSFilePath = / Users / macbookpro / Library / Developer / CoreSimulator / Devices / E58CA1C6-C6F1-4D72-9572-3925675E78A5 / data / Containers / Bundle / Application / EFA83E02-5F24 -4BB3-B32A-7E755081A730 / AutoLayout tuts.app/information.png,NSUnderlyingError = 0x7fb53251cd80 {Error Domain = NSPOSIXErrorDomain Code = 2“No such file or directory”}}

According to the fileManager.fileExistsAtPath() the file does indeed exist. 根据fileManager.fileExistsAtPath() ,文件确实存在。 What am I doing wrong? 我究竟做错了什么?

The problem is this line: 问题是这一行:

let fullDestPathString = String(fullDestPath)

It should be: 它应该是:

let fullDestPathString = fullDestPath.path

Look at the error. 看看错误。 The problem is the destination. 问题是目的地。 Notice the file:/// . 注意file:/// Your code is not properly converting the URL to a file path. 您的代码未正确将URL转换为文件路径。 You need to use the path property of NSURL to get the path as a string. 您需要使用NSURLpath属性将路径作为字符串。

In all of your debugging and checking, you never verified the value of fullDestPathString . 在所有调试和检查中,您从未验证fullDestPathString的值。

Swift 3 斯威夫特3

func copyfileToDocs()
    {
        let bundlePath = Bundle.main.path(forResource: "db", ofType: ".sqlite")
        print(bundlePath!, "\n") //prints the correct path
        let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let fileManager = FileManager.default
        let fullDestPath = NSURL(fileURLWithPath: destPath).appendingPathComponent("db.sqlite")
        let fullDestPathString = fullDestPath?.path
        print(fileManager.fileExists(atPath: bundlePath!)) // prints true
        do
        {
            try fileManager.copyItem(atPath: bundlePath!, toPath: fullDestPathString!)
            print("DB Copied")
        }
        catch
        {
            print("\n")
            print(error)
        }
    }

Swift 4 斯威夫特4

Misleading in some answers: 在一些答案中误导:

print(fileManager.fileExists(atPath: bundlePath!)) print(fileManager.fileExists(atPath:bundlePath!))

hence proposing this extension version: 因此提出这个extension版本:

extension FileManager {
    func copyfileToUserDocumentDirectory(forResource name: String,
                                         ofType ext: String) throws
    {
        if let bundlePath = Bundle.main.path(forResource: name, ofType: ext),
            let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                .userDomainMask,
                                true).first {
            let fileName = "\(name).\(ext)"
            let fullDestPath = URL(fileURLWithPath: destPath)
                                   .appendingPathComponent(fileName)
            let fullDestPathString = fullDestPath.path

            if !self.fileExists(atPath: fullDestPathString) {
                try self.copyItem(atPath: bundlePath, toPath: fullDestPathString)
            }
        }
    }
}

Usage 用法

try fileManager.copyfileToUserDocumentDirectory(forResource: "information",
                                                ofType: "png")
...

Please find Code Below.i have taken reference from @rmaddy's answer. 请找到Code Below.i,参考@ rmaddy的回答。

func CheckDataBaseOnPathorNot() -> Void {
        let bundlePath = Bundle.main.path(forResource: "Project_Expert", ofType: ".db")
        print(bundlePath ?? "", "\n") //prints the correct path
        let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let fileManager = FileManager.default
        let fullDestPath = NSURL(fileURLWithPath: destPath).appendingPathComponent("Project_Expert.db")
        let fullDestPathString = fullDestPath!.path
        print(fileManager.fileExists(atPath: bundlePath!)) // prints true
        if fileManager.fileExists(atPath: fullDestPathString) {
            print("File is available")
        }else{
            do{
                try fileManager.copyItem(atPath: bundlePath!, toPath: fullDestPathString)
            }catch{
                print("\n")
                print(error)

            }
        }

    }

Check this code for if the file is not available on the path, then copy the file. 如果文件在路径上不可用,请检查此代码,然后复制该文件。

Thank you. 谢谢。

to get the string path you should use this 要获取字符串路径,您应该使用它

let path = fullDestPath.path

On side note 旁注

fileManager.fileExistsAtPath(bundlePath!) == true 

is the way to check if the value if true 是检查值是否为true的方法

fileManager.fileExistsAtPath(bundlePath!)

just this can have some problems 这可能会有一些问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM