2014-03-04 292 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」)。