我在Windows 7 64位上.
我的程序需要从外部源检索一些文本(Utf8编码),用它做一些事情,然后将其保存到磁盘.原始文本使用"\ r \n"序列来表示换行符(我很高兴保持这种方式).
问题:当使用Data.Text.writeFile时,每个"\ r \n"序列似乎被翻译为"\ r \n \n \n",即每个'\n'被翻译为"\ r \n",甚至当它在原始文本中已经以'\ _'开头时.据我所知,在Windows操作系统上写入文件时,'\n'应转换为"\ r \n",如果前面没有'\ r',则将"\ r \n"转换为"\ r \n \n \n"似乎不正确.
使用ByteString.writeLine应用于textUtf8版本的文本工作得很好(没有额外的"\ r"插入"\ r \n"序列)
一个简单的例子:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as B
import qualified Data.Text as T
import qualified Data.Text.IO as T (writeFile)
import qualified Data.Text.Encoding as T (encodeUtf8)
str = "Line 1 is here\r\nLine 2 is here\r\nLine 3 is here" :: T.Text
main = do
B.writeFile "byt.bin" $ T.encodeUtf8 str
T.writeFile "txt.bin" str
Run Code Online (Sandbox Code Playgroud)
使用十六进制编辑器查看此代码生成的每个文件,可以看到通过T.writeFile行生成的文件中每个x0A前面添加的额外x0D.
B.writeFile:

T.writeFile:

我的问题:我做错了什么?有没有办法在Windows上使用T.writeFile,而不是将"\ r \n"翻译成"\ r \n \n \n"?
Nik*_* B. 10
你的答案在文档中:
从GHC 6.12开始,使用系统或句柄的当前语言环境和行结束约定来执行文本I/O.
由于您没有自己打开句柄,因此库很可能会以文本模式打开文件,从而导致操作系统翻译结束字符.您可以做的是使用二进制模式打开文件openBinaryFile,然后使用Data.Text.hPutStr以防止这种情况.
但是,处理编码的操作系统可能也不是您想要的.根据您的情况,像使用ByteStrings 一样明确地编码/解码字符串可能是更好的主意.