gpt4 book ai didi

haskell - Windows 上的 Data.ByteString.Lazy.Char8 换行符转换——文档是否具有误导性?

转载 作者:行者123 更新时间:2023-12-02 11:37:27 25 4
gpt4 key购买 nike

我对字节串库中的 Data.ByteString.Lazy.Char8 库有疑问。具体来说,我的问题涉及 readFile 函数,其记录如下:

Read an entire file lazily into a ByteString. Use 'text mode' on Windows to interpret newlines

我对这个函数将“使用 Windows 上的文本模式来解释换行符”的说法感兴趣。该函数的源码如下:

-- | Read an entire file /lazily/ into a 'ByteString'. Use 'text mode'
-- on Windows to interpret newlines
readFile :: FilePath -> IO ByteString
readFile f = openFile f ReadMode >>= hGetContents

我们看到,从某种意义上说,文档中的声明完全正确:已经使用了 openFile 函数(而不是 openBinaryFile),因此将为文件启用换行转换。

但是,文件将被传递给 hGetContents。这将调用 Data.ByteString.hGetNonBlocking (请参阅源代码 herehere ),它是 Data.ByteString.hGet 的非阻塞版本>(参见the documentation); (最后)Data.ByteString.hGet 调用 GHC.IO.Handle.hGetBuf (请参阅 the documentationthe source code )。该函数的documentation说的是

hGetBuf ignores whatever TextEncoding the Handle is currently using, and reads bytes directly from the underlying IO device.

这表明我们使用 readFile 而不是 readBinaryFile 打开文件的事实是无关紧要的:尽管文档中有声明,但数据将在不转换换行符的情况下被读取问题开头提到的。

所以,问题的核心是:1.我是不是漏掉了什么? “Data.ByteString.Lazy.Char8.readFile 在 Windows 上使用文本模式来解释换行符”这一说法是否正确?或者文档只是误导性的?

附注测试还表明,这个函数(至少当我简单地使用它时)在 Windows 上不会进行换行转换。

最佳答案

FWIW,软件包维护者 Duncan Coutts,回应了一些非常有帮助和启发性的评论。我已请求他允许将它们发布到此处,但在此期间,这里有一个释义。

基本点是文档曾经是正确的,但现在可能不正确了。特别是,当在 Windows 中打开文件时,操作系统本身允许您以“文本”或“二进制”模式打开它。 readFilereadBinaryFile 之间的区别过去是在操作系统的文本模式下打开文件,在 Win32 上以二进制模式打开文件。 (它们在 POSIX 上都会做同样的事情。)重要的是,如果您以操作系统的二进制模式打开一个文件,那么您不可能在没有换行符转换的情况下从文件中读取:它发生了总是

当事情像这样设置时,问题中提到的文档是正确的——Data.ByteString.Lazy.Char8.readFile将使用System.IO.readFile;这将告诉操作系统打开文件“Text”,并且即使使用 hGetBuf ,也会转换换行符。

然后,后来,Haskell 的 System.IO 得到了加强,使其对换行符的处理更加灵活——特别是允许 Haskell 版本在 POSIX 操作系统上运行,其中没有读取功能操作系统中内置了换行符修饰的文件,但仍支持使用 Windows 风格的换行符读取文件;或者更准确地说,支持Python风格'universal' newline conversion在两个操作系统上。这意味着:

  1. 换行符的处理被引入 Haskell 库;
  2. 无论您使用 readFile 还是 readBinaryFile,在 Windows 上文件始终以二进制模式打开;和
  3. 相反,readFilereadBinaryFile 之间的选择会影响 System.IO 的库代码是否设置为 >nativeNewlineModenoNewlineTranslation。然后,这将导致 Haskell 库转换为您执行适当的换行符转换。您现在还可以选择请求 universalNewlineMode

大约在同一时间,Haskell 在 System.IO 中内置了适当的编码支持(而不是假设输入为 latin-1 并简单地将输出字符截断为前 8 位)。总的来说,这是一件好事。

但是,至关重要的是,新的换行符转换现在已内置到库中,永远不会影响 hPutBuf 的功能——大概​​是因为构建新 的人们>System.IO 功能认为,如果以二进制方式读取细则,任何插入自身的换行符转换可能都不是程序员想要的,即是一个错误。事实上,99% 的情况可能都是如此:但在这种情况下,它会导致上述问题:-)

邓肯说,文档可能会发生变化,以在库的 future 版本中反射(reflect)这个美丽的新世界。在此期间,there is a workaround listed in another answer to this question.

关于haskell - Windows 上的 Data.ByteString.Lazy.Char8 换行符转换——文档是否具有误导性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6837628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com