ios 如何在 Swift 中访问包含在应用程序包中的文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37580015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:13:39  来源:igfitidea点击:

How to access file included in app bundle in Swift?

iosswiftfileread-write

提问by atirit

I know there are a few questions pertaining to this, but they're in Objective-C.

我知道有一些与此相关的问题,但它们在 Objective-C 中。

How can I access a .txtfile included in my app using Swift on an actual iPhone? I want to be able to read and write from it. Hereare my project files if you want to take a look. I'm happy to add details if necessary.

如何在实际 iPhone 上.txt使用 Swift访问我的应用程序中包含的文件?我希望能够从中读取和写入。如果你想看一看,是我的项目文件。如有必要,我很乐意添加详细信息。

回答by Karim H

Simply by searching in the app bundle for the resource

只需在应用程序包中搜索资源

var filePath = NSBundle.mainBundle().URLForResource("file", withExtension: "txt")

However you can't write to it because it is in the app resources directory and you have to create it in the document directory to write to it

但是你不能写入它,因为它在应用程序资源目录中,你必须在文档目录中创建它才能写入它

var documentsDirectory: NSURL?
var fileURL: NSURL?

documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last!
fileURL = documentsDirectory!.URLByAppendingPathComponent("file.txt")

if (fileURL!.checkResourceIsReachableAndReturnError(nil)) {
    print("file exist")
}else{
    print("file doesnt exist")
    NSData().writeToURL(fileURL!,atomically:true)
}

now you can access it from fileURL

现在您可以从fileURL访问它

EDIT - 28 August 2018

编辑 - 2018 年 8 月 28 日

This is how to do it in Swift 4.2

这是在Swift 4.2 中的方法

var filePath = Bundle.main.url(forResource: "file", withExtension: "txt")

To create it in the document directory

在文档目录中创建它

if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
   let fileURL = documentsDirectory.appendingPathComponent("file.txt")
   do {
       if try fileURL.checkResourceIsReachable() {
           print("file exist")
       } else {
           print("file doesnt exist")
           do {
            try Data().write(to: fileURL)
           } catch {
               print("an error happened while creating the file")
           }
       }
   } catch {
       print("an error happened while checking for the file")
   }
}

回答by Philippe-André Lorin

Swift 3, based on Karim's answer.

Swift 3,基于Karim 的回答

Reading

You can read files included in an app's bundle through the bundle's resource:

您可以通过捆绑包的资源读取应用程序捆绑包中包含的文件:

let fileURL = Bundle.main.url(forResource:"filename", withExtension: "txt")

Writing

写作

However, you can't write there. You will need to create a copy, preferably in the Documents directory:

但是,你不能在那里写。您需要创建一个副本,最好在 Documents 目录中:

func makeWritableCopy(named destFileName: String, ofResourceFile originalFileName: String) throws -> URL {
    // Get Documents directory in app bundle
    guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
        fatalError("No document directory found in application bundle.")
    }

    // Get URL for dest file (in Documents directory)
    let writableFileURL = documentsDirectory.appendingPathComponent(destFileName)

    // If dest file doesn't exist yet
    if (try? writableFileURL.checkResourceIsReachable()) == nil {
        // Get original (unwritable) file's URL
        guard let originalFileURL = Bundle.main.url(forResource: originalFileName, withExtension: nil) else {
            fatalError("Cannot find original file “\(originalFileName)” in application bundle's resources.")
        }

        // Get original file's contents
        let originalContents = try Data(contentsOf: originalFileURL)

        // Write original file's contents to dest file
        try originalContents.write(to: writableFileURL, options: .atomic)
        print("Made a writable copy of file “\(originalFileName)” in “\(documentsDirectory)\\(destFileName)”.")

    } else { // Dest file already exists
        // Print dest file contents
        let contents = try String(contentsOf: writableFileURL, encoding: String.Encoding.utf8)
        print("File “\(destFileName)” already exists in “\(documentsDirectory)”.\nContents:\n\(contents)")
    }

    // Return dest file URL
    return writableFileURL
}

Example usage:

用法示例:

let stuffFileURL = try makeWritableCopy(named: "Stuff.txt", ofResourceFile: "Stuff.txt")
try "New contents".write(to: stuffFileURL, atomically: true, encoding: String.Encoding.utf8)

回答by CodeBender

Just a quick update for using this code with Swift 4:

只是在 Swift 4 中使用此代码的快速更新:

Bundle.main.url(forResource:"YourFile", withExtension: "FileExtension")

And the following has been updated to account for writing the file out:

并且已更新以下内容以说明写出文件:

var myData: Data!

func checkFile() {
    if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
        let fileURL = documentsDirectory.appendingPathComponent("YourFile.extension")
        do {
            let fileExists = try fileURL.checkResourceIsReachable()
            if fileExists {
                print("File exists")
            } else {
                print("File does not exist, create it")
                writeFile(fileURL: fileURL)
            }
        } catch {
            print(error.localizedDescription)
        }
    }
}

func writeFile(fileURL: URL) {
    do {
        try myData.write(to: fileURL)
    } catch {
        print(error.localizedDescription)
    }
}

This particular example is not the most flexible, but with a little bit of work you can easily pass in your own file names, extensions and data values.

这个特殊的例子并不是最灵活的,但是通过一些工作,您可以轻松地传递您自己的文件名、扩展名和数据值。

回答by MirekE

Bundles are read only. You can use NSBundle.mainBundle().pathForResourceto access the file as read-only, but for read-write access you need to copy your document to Documents folder or tmp folder.

捆绑包是只读的。您可以使用NSBundle.mainBundle().pathForResource以只读方式访问文件,但要进行读写访问,您需要将文档复制到 Documents 文件夹或 tmp 文件夹。

回答by Mithilesh Kuamr

Get File From Bundle in Swift 5.1

在 Swift 5.1 中从包中获取文件

//For Video File
let stringPath = Bundle.main.path(forResource: "(Your video file name)", ofType: "mov")

let urlVideo = Bundle.main.url(forResource: "Your video file name", withExtension: "mov")

回答by T.Nhan

Bundles can be written. You can use Bundle.main.pathto overwrite file by adding it into Copy Bundles Resource.

可以写包。您可以Bundle.main.path通过将文件添加到Copy Bundles Resource.

Project ->Target ->Build Pharse ->Copy Bundles Resource

项目 ->目标 ->构建阶段 ->复制捆绑资源