2014-03-04 240 views
1

我正在编写一个程序,它将文本文件列表作为参数,并输出一个文件,其中每行是文件中相应行之间的标签插入。Data.ByteString输出不正确

假设所有字符是ASCII编码

import GHC.IO.Handle 
import System.IO 
import System.Environment 
import Data.List 

main = do 
    (out:files) <- getArgs 
    hs <- mapM (`openFile` ReadMode) files 
    txts <- mapM B.hGetContents hs 
    let final = map (B.intercalate (B.singleton '\t')) . transpose 
       . map (B.lines . B.filter (/= '\t')) $ txts 
    withFile out WriteMode $ \out -> 
     B.hPutStr out (B.unlines final) 
    putStrLn "Completed successfully" 

的问题是,它输出:

file1row1 
    file2row1 
file1row2 
    file2row2 
file1row3 
    file2row3 

代替:

file1row1 file2row1 
file1row2 file2row2 
file1row3 file2row3 

同样的逻辑正常工作进行测试时通过在ghci中手动定义函数。当使用Data.Text.Lazy而不是懒惰的Bytestring时,相同的代码可正常工作。

我的方法有什么问题?

回答

2

Data.ByteString.Lazy.UTF8中存在一个已知的错误,即使文档说明它应该这样,新行转换不能正确发生。 (请参阅Data.ByteString.Lazy.Char8 newline conversion on Windows---is the documentation misleading?)这可能是您的问题的原因。

+0

我使用'Data.ByteString.Lazy.Char8'而不是'UTF8'。你能详细解释一下这个问题吗,我似乎不明白发生了什么事情。 – haskelline

+0

换行字符都是ASCII字符,并且应该在单字节读取时工作得很好。 – haskelline

+0

好的,我在另一个问题上看了一下你的解决方法,我有点了解发生了什么。这个问题到现在为止还没有解决方案,这不是很奇怪吗? – haskelline

2

当我在样品测试字符串Data.ByteString.Lazy.UTF8.lines,它没有删除“\ r” ....

ghci -XOverloadedStrings 

> import Data.ByteString.Lazy.UTF8 as B 

> B.lines "ab\n\rcd" 
    ["ab","\rcd"] 

> B.lines "ab\r\ncd" 
    ["ab\r","cd"] 

我猜这是你的问题。 (验证,你可以使用“xxd”或任何其他十六进制编辑器查看输出....查看额外字符实际上是否是“\ r”)。