swift String(contentsOf:URL).data(使用:.utf8)与Data(contentsOf:URL)

nx7onnlm  于 2023-08-02  发布在  Swift
关注(0)|答案(1)|浏览(284)

我一直在操场上玩json文件,我看到了像这样阅读文件的例子:

do {
    let jsonData = try String(contentsOf: url).data(using: .utf8)
} catch {
    ...
}

字符串
就像这样:

do {
    let jsonData = try Data(contentsOf: url)
} catch {
    ...
}


数据是否存在差异?我看到的唯一区别是String数据方法在读取时被格式化为UTF8,而我假设Data方法使用默认格式阅读(也是UTF8?不过,我看不出数据有什么不同,只是想确定一下。

jyztefdp

jyztefdp1#

不同之处在于String(contentsOf: url)尝试从该URL读取 text,而Data(contentsOf: url)读取原始 bytes
因此,如果URL处的文件不是纯文本文件,String(contentsOf: url)可能会抛出错误,而Data(contentsOf: url)会成功读取它。
关于编码,String(contentsOf: url)没有文档,但从它的实现中,我们可以看到它调用NSString.init(contentsOf:usedEncoding:)

public init(
    contentsOf url: __shared URL
    ) throws {
    let ns = try NSString(contentsOf: url, usedEncoding: nil)
    self = String._unconditionallyBridgeFromObjectiveC(ns)
}

字符串
NSString.init(contentsOf:usedEncoding:)is documented:
返回通过从给定URL阅读数据初始化的NSString对象,并通过引用返回用于解释数据的编码。
所以显然编码是 guessed(?)并通过引用返回,然后被String.init(contentsOf:)忽略,因为它为usedEncoding参数传递了nil
这意味着对于一些非UTF-8文件,String(contentsOf:)有可能猜测正确的编码,然后data(using: .utf8)将字符串编码为UTF-8字节,使其余代码正常工作。如果您使用了Data(contentsOf:),那么您将阅读错误的编码,尽管它不会抛出错误,但稍后的JSON解析代码可能会抛出错误。
也就是说,JSON应该在UTF-8中交换(参见RFC),所以当你读取非UTF-8文件时可能会出现错误。
所以基本上,如果我们在这两个选项中选择,只需使用Data(contentsOf:)。它更简单,打字更少。您不需要担心编码错误或文件不是纯文本等问题。如果发生了类似的情况,它不是JSON,后面的JSONDecoder将抛出。

相关问题