Haskell中使用readFile存在字符编码问题

6

虽然我遇到了很多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 函数,或者只需跳过该文本文件并进入下一个。
2个回答

5
由于其他回答中提到的所有原因,这并不容易。但是并非一无所获。使用charsetdetect——它基于Mozilla算法,可以检测每个字节串的编码。然后将检测到的编码传递给text-icuencoding进行解码。对于最奇怪和晦涩的文本编码,检测可能无法正常工作,但对于其他情况应该可以。

2
你想要的是不可能的,原因如下:
有许多8位编码,其中所有或大部分可能的8位模式都被分配给某些字符,根本没有办法找出是哪种编码。你绝对需要事先知道编码的内容:例如俄文或希腊文本?还是只有偶尔会有ä或ß的德文?
因此,聪明人发明了Unicode和UTF-8,你所需做的就是:
  • 将所有文本都用UTF-8编写
  • 不接受任何非UTF-8编码的文件
  • 当发现文件以所谓的“字节顺序标记”(BOM)开头时,取消所有声称提供UTF-8编码文件的人的社交关系。
让坚持使用40年老旧专有编码的人成为少数,并且即使是像微软这样的巨头也将不得不放弃他们不良习惯!

谢谢您的回答。我同意,使用正确的方法几乎不可能处理所有编码。但是:也许有一些方法可以事先检测到至少一些编码。如果不可能并且抛出异常,我希望我的程序继续尝试另一个readFile函数或者只是跳过那个文本文件并进入下一个。 - phynfo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接