Data.ByteString.hGetContents的文档说
与 hGet 一样,文件中的字符串表示假定为 ISO-8859-1。
为什么它必须“假设”关于“文件中的字符串表示”的任何内容?数据根本不一定是字符串或编码文本。如果我想要处理编码文本,我会使用 Data.Text 或者 Data.ByteString.Char8。我认为 ByteString 的全部意义在于数据被处理为 8 位字节列表,而不是文本字符。假设它是 ISO-8859-1 有什么影响?
Data.ByteString.hGetContents的文档说
与 hGet 一样,文件中的字符串表示假定为 ISO-8859-1。
为什么它必须“假设”关于“文件中的字符串表示”的任何内容?数据根本不一定是字符串或编码文本。如果我想要处理编码文本,我会使用 Data.Text 或者 Data.ByteString.Char8。我认为 ByteString 的全部意义在于数据被处理为 8 位字节列表,而不是文本字符。假设它是 ISO-8859-1 有什么影响?
这是一种迂回的说法 - 不执行解码(因为编码是 8 位,不需要做任何事情),所以hGetContents
给你 0x00 - 0xFF 范围内的字节:
$ cat utf-8.txt
ÇÈÄ
$ iconv -f iso8859-1 iso8859-1.txt
ÇÈÄ
$ ghci
> openFile "iso8859-1.txt" ReadMode >>= (\h -> fmap BS.unpack $ BS.hGetContents h)
[199,200,196,10]
> openFile "utf-8.txt" ReadMode >>= (\h -> fmap BS.unpack $ BS.hGetContents h)
[195,135,195,136,195,132,10]
也许它类似于this,那么:
在某些情况下,编码处理不正确,但事情仍然有效。经常遇到的情况是设置为 latin-1 的数据库和使用 UTF-8(或任何其他编码)的应用程序。几乎任何 1 和 0 的组合在单字节 latin-1 编码方案中都是有效的。如果数据库从一个看起来像 11100111 10111000 10100111 的应用程序接收到文本,它会很乐意存储它,认为该应用程序打算存储三个拉丁字符“縧”。毕竟,为什么不呢?然后它稍后将此位序列返回给应用程序,应用程序会很乐意将其作为“绦”的 UTF-8 序列接受,它最初存储的。数据库管理界面会自动确定数据库设置为 latin-1,并将任何文本解释为 latin-1,