2016-01-14 75 views
2

雖然我經歷了一堆哈斯克爾-編碼的問題,問題的跑到我是不是能夠沿着以下問題得到:哈斯克爾字符編碼問題READFILE

我想讀許多不同的文本文件;文件的字符編碼可能不一致,並且我使用的任何readFile函數在讀取某些文件時都會拋出異常。

我試圖壓縮這個問題:以下情況總結了它的核心。

import Prelude hiding (writeFile, readFile) 
import qualified Text.Pandoc.UTF8 as UTF (readFile, writeFile, putStr, putStrLn) 
import qualified Prelude as Prel (writeFile, readFile) 
import Data.ByteString.Lazy (ByteString, writeFile, readFile) 

,並在ghci中我得到如下結果:

*Main> Prel.readFile "Test/A.txt" 
*** Exception: Test/A.txt: hGetContents: invalid argument (invalid byte sequence) "\226\8364 
*Main> Prel.readFile "Test/C.txt" 
"\8230\n" 

*Main> UTF.readFile "Test/A.txt" 
"\8221\n" 

*Main> UTF.readFile "Test/C.txt" 
*** Exception: Cannot decode byte '\x85':  
Data.Text.Internal.Encoding.Fusion.streamUtf8: Invalid UTF-8 stream 

也許下面的相關信息幫助:

  • getLocaleEncoding產量CP1252
  • 的兩個 「問題」 的字節串文本文件:

*Main> readFile "Test/A.txt" "\226\128\157\r\n" *Main> readFile "Test/C.txt" "\133\r\n"

我的問題是:我如何能趕上/處理/避免這些字符編碼錯誤?重點是:我不知道預先編碼的文本文件,我需要一個適用於所有文件的readFile方法。 如果不可能,並且拋出異常時,我想要捕獲異常並執行我的程序以便能夠嘗試另一個readFile函數,或者只是跳過該文本文件並轉到下一個。

回答

3

由於所有其他答案提到的原因,這並不容易。但一切都不會丟失。使用charsetdetect - 它基於Mozilla算法,顯然 - 檢測每個字符串的編碼。然後將檢測到的編碼傳遞給text-icuencoding進行解碼。檢測不適用於最奇怪和最深刻的文本編碼,但它應該工作。

2

你想要什麼是不可能的,原因如下:

有所有或大部分可能的8位模式分配給一些性格很多很多8位編碼。根本沒有辦法找出它是哪個編碼。你絕對需要事先知道它是什麼編碼的:可能是俄文或希臘文的文本?或者只是德語,其中大多數字符將在7位ASCII平面中,並且偶爾會有一個ä或一個ß。

爲此,聰明人發明了Unicode和UTF-8,所有你需要做的就是:從今天開始,我會

  • 寫在UTF-8
  • 不接受所有文本任何不是UTF-8編碼的文件。
  • 將取消所有與提供已編碼的UTF-8編碼文件的人的所有社交關係,當事實證明文件以所謂的「字節順序標記」(BOM)開頭時。

讓我們讓那些堅持40歲的專有編碼的人成爲少數,甚至像微軟這樣的巨人也將被迫放棄他們的壞習慣!

+0

謝謝你的回答。我同意,用適當的方法處理所有**編碼幾乎是不可能的。但是:也許有些方法可以事先檢測至少一些編碼。如果不可能,並且拋出異常時,我希望程序繼續並嘗試另一個readFile函數,或者只是簡單地跳過該文本文件並轉到下一個。 – phynfo