2016-01-21 33 views
3

當我嘗試讀取一個爲Text的UTF8文本文件時,我試圖使用Data.Text.IO.readFile
但是,當系統環境的語言環境不是*.UTF8(特別是c)時,它不起作用。
它說hGetContents: invalid argument (invalid byte sequence)有沒有辦法處理與Data.Text.IO.hGetContents編碼?

是的,我讀了文件Data.Text.IO區域支持的一部分。 它說Data.Text.IO取決於系統環境的設置。

因此,我嘗試使用Data.Text.IO.hGetContents功能與System.IO.hSetEncoding h System.IO.utf8_bom
這個工程,當我用它System.IO.hGetContents

但是,與Data.Text.IO.hGetContents,它說text: <stdout>: commitAndReleaseBuffer: invalid argument (invalid character)

有沒有辦法處理編碼Data.Text.IO.hGetContentsData.Text.IO.readFile而不改變系統環境變量如LANG? 只需編輯Haskell代碼的方法是首選。

這裏是我的原代碼:

import qualified Data.Text as T 
import qualified Data.Text.IO as T 

main = do 
    text <- T.readFile "./data.md" 
    T.putStrLn text 

這裏是我的審判代碼:

import qualified Data.Text as T 
import qualified Data.Text.IO as T 

import System.IO 

main = do 
    h <- System.IO.openFile "./data.md" System.IO.ReadMode 
    System.IO.hSetEncoding h System.IO.utf8_bom 
    text <- T.hGetContents h -- `System.IO.hGetContents h` works! 
    T.putStrLn text 

這些作品時,系統的locale是*.UTF8,並未能與其他環境。

測試環境的信息:

  • 的Linux(Ubuntu的14.04)
  • GHC 7.10.3
  • text 1.2.2.0
+0

對於任何需要在'data.md'中隨機使用非ASCII字符的人來測試這個:'äüöÄÜÖßáéúíóð¾<èÉ쀆â'r'' – Zeta

回答

4

我變得有點不同的錯誤:

<stdout>: hPutChar: invalid argument (invalid character) 

I即使使用System.IO.hGetContents也會得到相同的錯誤。不知道爲什麼你的行爲不同。 (我使用ghc-7.10.2text-1.2.1.3

要回答這個問題:您正在試圖UTF-8 -encoded字符串給stdout,配置爲ASCII。我不知道它應該輸出什麼。

如果你的終端實際接受UTF-8,那麼你可以配置stdout忽略當前的語言環境,並接受UTF-8

main = do 
    h <- System.IO.openFile "./data.md" System.IO.ReadMode 
    System.IO.hSetEncoding h System.IO.utf8_bom 
    text <- T.hGetContents h 
    System.IO.hSetEncoding stdout System.IO.utf8_bom 
    T.hPutStrLn stdout text 
+0

謝謝,它適用於我。我認爲我的環境接受'stdout'的'UTF-8'。我測試了這個示例代碼,以部署一個新貴的Linux服務。 – QuietJoon

1

正確的方法做,這是讀取該文件與bytestring和使用text-icu爲{恩,德}編碼。 (這在text文檔中提到:「要使用擴展和非常豐富的函數系列來處理Unicode文本...,請參閱text-icu程序包」。

import qualified Data.ByteString as BS 
import qualified Data.Text.ICU.Convert as ICU 

import System.IO 

main = do 
    -- dunno what the Nothing argument is for, read the docs! 
    conv <- ICU.open "utf-8" Nothing 
    h <- openFile "test.txt" System.IO.ReadMode 
    bs <- BS.hGetContents h 
    print (ICU.toUnicode conv bs) 

注::)例如,下面的哈斯克爾文件既LANG=en_US.utf8LANG=C正確地讀我的測試文件我呼叫print而不是T.putStrLn - 因爲輸出到我的終端將取決於區域設置!

相關問題