12
readFile "file.html"
"start of the file... *** Exception: file.html: hGetContents: invalid argument (invalid code page byte sequence)

这是一个用 notepad++ 创建的 UTF-8 文件……我怎样才能在 haskell 中读取文件?

4

2 回答 2

13

默认情况下,文件是在系统语言环境中读取的,所以如果你有一个使用非标准编码的文件,你需要自己设置文件句柄的编码。

foo = do
    handle <- openFile "file.html" ReadMode
    hSetEncoding handle utf8_bom
    contents <- hGetContents handle
    doSomethingWithContents
    hClose handle

应该让你开始。请注意,这不包含错误处理,因此更好的方法是

import Control.Exception -- for bracket

foo = bracket
        (openFile "file.html" ReadMode >>= \h -> hSetEncoding h utf8_bom >> return h)
        hClose
        (\h -> hGetContents h >>= doSomething)

或者

foo = withFile "file.html" ReadMode $
        \h -> do hSetEncoding h utf8_bom
                 contents <- hGetContents h
                 doSomethingWith contents
于 2012-10-15T20:33:53.130 回答
2

根据此站点,您的 6 字节解码如下:

EF BB BF -> ZERO WIDTH NO-BREAK SPACE (i.e. the BOM, although its not needed in UTF-8
C4 8D    -> LATIN SMALL LETTER C WITH CARON (what you said)
0D       -> CARRIAGE RETURN (CR)

所以它是一个合法的 UTF-8 序列。

然而,标准的 Prelude 函数最初只是做 ASCII。我不知道他们现在在做什么,但请参阅这个问题GHC/Haskell How does GHC/Haskell 决定它将从/到解码/编码的字符编码?更多的想法。然后使用http://hackage.haskell.org/package/utf8-string代替 Prelude 函数。

于 2012-10-15T21:20:41.597 回答