如何将Dictionary写入文件? [英] How to write Dictionary to a file?

查看:347
本文介绍了如何将Dictionary写入文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个FileHelper类,在其中实现了3种方法,其作用是将Dictionary的内容写入文件.这些方法是:

I have a FileHelper class where I've implemented 3 methods whose job is to write a Dictionary contents to a file. Those methods are:

func storeDictionary(_ dictionary: Dictionary<String, String>, inFile fileName: String, atDirectory directory: String) -> Bool {
    let ext = "txt"
    let filePath = createFile(fileName, withExtension: ext, atDirectory: directory)
    /**** //If I use this method, file is created and dictionary is saved
    guard (dictionary as NSDictionary).write(to: filePath!, atomically: true) else {
        return false
    }
    */
    guard NSKeyedArchiver.archiveRootObject(dictionary, toFile: (filePath?.absoluteString)!) else {
        return false
    }
    return true
}
func createFile(_ file: String, withExtension ext: String, atDirectory directory: String) -> URL? {
    let directoryPath = createDirectory(directory)
    let filePath = directoryPath?.appendingPathComponent(file).appendingPathExtension(ext)

    if !FileManager.default.fileExists(atPath: (filePath?.absoluteString)!) {
        let success = FileManager.default.createFile(atPath: (filePath?.absoluteString)!, contents: nil, attributes: nil)
        print("\(success)") //** here is the issue I investigated. Always prints false.
    }

    return filePath
}
func createDirectory(_ directory: String) -> URL? {
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let directoryPath = documentsDirectory.appendingPathComponent(directory)

    do {
        try FileManager.default.createDirectory(at: directoryPath, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
        fatalError("Error creating directory: \(error.localizedDescription)")
    }
    return directoryPath
}

当我调用FileHelper().storeDictionary(aValidDictionary, inFile: "abc", atDirectory: "XYZ")编写字典时,此过程失败.但是,如果我使用

When I call FileHelper().storeDictionary(aValidDictionary, inFile: "abc", atDirectory: "XYZ") to write the dictionary, it fails with this procedure. But if I use

guard (dictionary as NSDictionary).write(to: filePath!, atomically: true) else {
    return false
}

有效.

NSKeyedArchiver.archiveRootObject(_:toFile:)方法有什么问题?

为什么FileManager.default.createFile(atPath: (filePath?.absoluteString)!, contents: nil, attributes: nil)总是返回false?

And why FileManager.default.createFile(atPath: (filePath?.absoluteString)!, contents: nil, attributes: nil) always returns false?

推荐答案

首先filePath?.absoluteString返回整个字符串-包括转义百分比的字符串-包括file://方案,并且该方法期望使用不带方案的路径(-命名有点混乱;-)).

First of all filePath?.absoluteString returns the entire – even percent escaped – string including the file:// scheme and the method expects a path without the scheme (filePath?.path - the naming is a bit confusing ;-) ).

我建议将[String:String]词典另存为属性列表文件.无需显式创建文件.

I recommend to save a [String:String] dictionary as property list file. It's not necessary to create the file explicitly.

我在 Swift-3-way 中略微更改了方法的签名.此外,无需使用任何可选类型.

I changed the signatures of the methods slightly in the Swift-3-way. Further there is no need to use any optional type.

func store(dictionary: Dictionary<String, String>, in fileName: String, at directory: String) -> Bool {
    let fileExtension = "plist"
    let directoryURL = create(directory:directory)
    do {
        let data = try PropertyListSerialization.data(fromPropertyList: dictionary, format: .xml, options: 0)
        try data.write(to: directoryURL.appendingPathComponent(fileName).appendingPathExtension(fileExtension))
        return true
    }  catch {
        print(error)
        return false
    }
}

func create(directory: String) -> URL {
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let directoryURL = documentsDirectory.appendingPathComponent(directory)

    do {
        try FileManager.default.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
        fatalError("Error creating directory: \(error.localizedDescription)")
    }
    return directoryURL
}

PS:您可以使存储方法可以抛出并处理调用方法中的错误,而不是返回Bool:

PS: Instead of returning a Bool you could make the store method can throw and handle the error in the calling method:

func store(dictionary: Dictionary<String, String>, in fileName: String, at directory: String) throws {
    let fileExtension = "plist"
    let directoryURL = create(directory:directory)

    let data = try PropertyListSerialization.data(fromPropertyList: dictionary, format: .xml, options: 0)
    try data.write(to: directoryURL.appendingPathComponent(fileName).appendingPathExtension(fileExtension))
}

这篇关于如何将Dictionary写入文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆