【问题标题】:Getting "The file couldn’t be opened because there is no such file" error from FileManager even though it's actually opened从 FileManager 获取“无法打开文件,因为没有这样的文件”错误,即使它实际上已打开
【发布时间】:2020-11-28 02:36:00
【问题描述】:

我正在检索一个plist 文件,对其进行更新并将其写入磁盘。

1) 检索

func pListURL() -> URL? {
     guard let result = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("somePlist.plist") else { return nil }
     return result
 }

2) 更新

var data: [String: Int] = [:]
if let url = pListURL() {
    do {
        let dataContent = try Data(contentsOf: url)
        if let dict = try PropertyListSerialization.propertyList(from: dataContent, format: nil) as? [String: Int] {
            data = dict
        }
    } catch {
        print(error)
    }
}

// update code

3) 写

if let path = pListURL() {
    do {
        let plistData = try PropertyListSerialization.data(fromPropertyList: data, format: .xml, options: 0)
        try plistData.write(to: path)
    } catch {
        print(error)
    }
}

奇怪的是我收到一条错误消息:

文件“somePlist.plist”无法打开,因为没有这样的文件。

即使当我检查plist 时,它实际上已按应有的方式正确创建和更新。据我所知,FileManager.default.url(for:in:appropriateFor:create: )create 参数确保它“如果目录不存在则创建目录”,这意味着如果plist 不存在,则创建somePlist.plist

【问题讨论】:

    标签: ios swift plist nsfilemanager


    【解决方案1】:

    据我所知, FileManager.default.url(for:in:appropriateFor:create: ) 的 create 参数确保它“如果目录不存在则创建目录”,这意味着创建了 somePlist.plist如果 plist 不存在。

    不,这意味着 目录 已创建,但 文件 创建。

    update 部分忽略couldn’t be opened 错误并将(新)数据写入磁盘或使用fileExists(atPath 检查文件是否存在。

    您可以将pListURL 中的返回值声明为非可选。保证Documents文件夹存在

    func pListURL() -> URL {
         return try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("somePlist.plist")
    }
    

    更新:

    这些是updatewrite 的可靠版本

    func update(dictionary: [String:Int]) {
        let url = pListURL()
        guard FileManager.default.fileExists(atPath: url.path) else { write(dictionary: dictionary); return }
        do {
            let dataContent = try Data(contentsOf: url)
            if var dict = try PropertyListSerialization.propertyList(from: dataContent, format: nil) as? [String: Int] {
                for (key, value) in dictionary {
                    dict.updateValue(value, forKey: key)
                }
                write(dictionary: dict)
            } else {
                write(dictionary: dictionary)
            }
        } catch {
            print(error)
        }
    }
    
    func write(dictionary: [String:Int]) {
        let url = pListURL()
        do {
            let plistData = try PropertyListSerialization.data(fromPropertyList: dictionary, format: .xml, options: 0)
            try plistData.write(to: url)
        } catch {
            print(error)
        }
    }
    

    【讨论】:

    • 当您说“忽略无法打开的错误”时,您的意思是将写入磁盘的代码放在catch中吗?
    • 是的,但是您需要捕获特定的couldn’t be opened 错误。我更愿意在 do 块之前检查文件是否存在。
    • 我会在检索过程中检查文件是否存在于pListURL() 函数中,对吗?
    • 其实这没什么用,因为即使文件不存在也必须返回 URL。或仅返回基本文档文件夹 URL。
    • 如果文件不存在,我认为不需要URL。在写入过程中将创建一个带有新URL 的新文件。
    猜你喜欢
    • 2016-10-07
    • 2014-11-23
    • 2016-02-18
    • 2017-09-29
    • 2014-08-25
    • 2016-07-15
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多