2011-12-20 163 views
2

當我試圖從我的Haskell程序中讀取的純文本文件,我得到:字符編碼問題

[fromlist裏*異常:/path/to/file/aaa.txt hGetContents:無效的參數(無效或不完整的多字節或寬字符)

我用Google搜索以發現此問題通常通過將LANG設置爲en_US.UTF-8 來設置。這已經是我的語言環境的外觀了。

不確定這是否與GHC有關。

我在Ubuntu 11.10

回答

4

確定aaa.txt包含有效的UTF-8?如果是二進制數據,則需要使用withBinaryFile或類似的。如果是另一種編碼的文本,則應使用hSetEncoding

舉例來說,如果你的文本是Latin-1的,那麼你會說

hSetEncoding h latin1 

其中, 「H」 是你的文件句柄。如果你是從標準輸入讀那麼它

hSetEncoding stdin latin1 

還有一個mkTextEncoding功能,您可以使用,如果您已經閱讀從元數據編碼,或想自定義無效的Unicode的處理(雖然這僅適用於一些系統)。

Unicode標準說Unicode解析器應該拒絕錯誤的無效字符串,而不是試圖修復它們。這是故意拒絕Postel's Law,理由是減少安全漏洞和不一致的解釋。

(如果您需要處理大量文本並且需要處理編碼問題,您可能會考慮使用text庫;它通常比使用Strings更快,因爲它使用的是非裝箱數組而非鏈接列表,儘管這意味着文本值和對它們的操作必然是嚴格的,它還允許您更靈活地配置how to respond to invalid Unicode。)

+0

這些是來自gutenberg的純文本文件。我只是檢查,文件說「字符集編碼:ISO拉丁-1」什麼是使用hSetEncoding的方式?我無法找到一個例子。我試着把行hSetEncoding =「latin1」,它編譯,但給出了相同的錯誤 – atlantis 2011-12-20 09:21:02

+1

'hSetEncoding h latin1',其中'h'是你的文件句柄。你讀過一個Haskell教程嗎?沒有冒犯,只是它使得像使用標準庫函數更容易:) – ehird 2011-12-20 09:55:22

+1

(您可以看到TextEncoding值列表[here](http://hackage.haskell.org/packages/archive/base/latest/doc /html/System-IO.html#t:TextEncoding);等價地,通過單擊同一頁上的hSetEncoding類型簽名中的TextEncoding鏈接)。 – ehird 2011-12-20 09:56:06