我一直在操场上玩json文件,我看到了像这样阅读文件的例子:
do {
let jsonData = try String(contentsOf: url).data(using: .utf8)
} catch {
...
}
字符串
就像这样:
do {
let jsonData = try Data(contentsOf: url)
} catch {
...
}
型
数据是否存在差异?我看到的唯一区别是String数据方法在读取时被格式化为UTF8,而我假设Data方法使用默认格式阅读(也是UTF8?不过,我看不出数据有什么不同,只是想确定一下。
1条答案
按热度按时间jyztefdp1#
不同之处在于
String(contentsOf: url)
尝试从该URL读取 text,而Data(contentsOf: url)
读取原始 bytes。因此,如果URL处的文件不是纯文本文件,
String(contentsOf: url)
可能会抛出错误,而Data(contentsOf: url)
会成功读取它。关于编码,
String(contentsOf: url)
没有文档,但从它的实现中,我们可以看到它调用NSString.init(contentsOf:usedEncoding:)
:字符串
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
将抛出。