readFile "file.html"
"start of the file... *** Exception: file.html: hGetContents: invalid argument (invalid code page byte sequence)
Это файл UTF-8, созданный с помощью блокнота ++... как я могу прочитать файл в haskell?
readFile "file.html"
"start of the file... *** Exception: file.html: hGetContents: invalid argument (invalid code page byte sequence)
Это файл UTF-8, созданный с помощью блокнота ++... как я могу прочитать файл в haskell?
По умолчанию файлы читаются в локали системы, поэтому, если у вас есть файл с использованием нестандартного кодирования, вам нужно установить кодировку дескриптора файла самостоятельно.
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
Согласно этот сайт, ваши 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 решает, какую кодировку символов он собирается декодировать/кодировать из/в? еще несколько идеи. А затем используйте http://hackage.haskell.org/package/utf8-string вместо функций Prelude.