readFile的Haskell字符编码问题

readFile的Haskell字符编码问题,haskell,character-encoding,Haskell,Character Encoding,虽然我经历了一系列Haskell编码问题,但我无法解决以下问题: 我想读很多不同的文本文件;文件的字符编码可能不一致,我使用的任何readFile函数在读取某些文件时都会抛出异常 我试图把问题浓缩起来:下面的情况概括了问题的核心 import Prelude hiding (writeFile, readFile) import qualified Text.Pandoc.UTF8 as UTF (readFile, writeFile, putStr, putStrLn) import qua

虽然我经历了一系列Haskell编码问题,但我无法解决以下问题:

我想读很多不同的文本文件;文件的字符编码可能不一致,我使用的任何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
  • 两个“有问题”文本文件的ByteString:

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

我的问题是:如何发现/处理/避免这些字符编码错误?问题是:我事先不知道文本文件的编码,我需要一个适用于所有人的readFile方法。
如果不可能,当抛出异常时,我希望捕获异常并继续我的程序,以便能够尝试另一个readFile函数,或者干脆跳过该文本文件并转到下一个

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

有很多很多8位编码,其中所有或大多数可能的8位模式都分配给某个字符。根本没有办法找出它是哪种编码。你绝对需要事先知道编码的是什么:也许是俄语或希腊语文本?或者只是德语,其中大多数字符将在7位ASCII平面中,只有偶尔会出现ä或ß

出于这个原因,聪明人发明了Unicode和UTF-8,你所需要做的就是说:从今天开始,我会

  • 用UTF-8书写所有文本
  • 不接受任何非UTF-8编码的文件
  • 当文件以所谓的“字节顺序标记”(BOM)开头时,将取消与提供所有UTF-8编码文件的人员的所有社交关系

让我们让坚持使用已有40年历史的专有编码的人成为少数,甚至像微软这样的巨头也将被迫放弃他们的坏习惯

由于其他答案提到的所有原因,这并不容易。但这一切并没有失去。显然,它基于Mozilla算法,用于检测每个bytestring的编码。然后将检测到的编码传递给或进行解码。检测对最奇怪和最深奥的文本编码不起作用,但对其余的应该起作用。

谢谢你的回答。我同意,用正确的方法处理所有编码几乎是不可能的。但是:也许有一些方法可以预先检测到至少一些编码。如果不可能,当抛出异常时,我希望我的程序继续并尝试另一个readFile函数,或者干脆跳过该文本文件并转到下一个。