虽然我经历了一堆Haskell编码 - 问题 - 问题我无法解决以下问题:
我想阅读许多不同的文本文件;文件的字符编码可能不一致,我正在使用的任何readFile-Function都会在读取某些文件时抛出异常。
我试图压缩问题:以下情况总结了它的核心。
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函数或者只是跳过该文本文件然后转到下一个。
答案 0 :(得分:3)
由于所有其他答案提到的原因,这并不容易。但一切都不会丢失。使用charsetdetect - 显然是基于Mozilla算法 - 检测每个字节串的编码。然后将检测到的编码传递给text-icu或encoding进行解码。检测不适用于最奇怪和最晦涩的文本编码,但其余部分应该有效。
答案 1 :(得分:2)
您想要的是不可能的,原因如下:
有许多8位编码,其中所有或大多数可能的8位模式都分配给某个字符。根本没有办法找出它是哪种编码。你绝对需要事先知道编码的是什么:一些俄语或希腊文,也许吧?或者只是德语,其中大多数字符将在7位ASCII平面中,并且偶尔会有ä或ß。
出于这个原因,聪明人发明了Unicode和UTF-8,你需要做的就是说:从今天起我会
让那些坚持使用40年历史的专有编码成为少数人的人,即使像微软这样的巨头也会被迫放弃他们的坏习惯!