在Haskell中使用"US-ASCII"编码读取文件:hGetContents: 无效参数(无效的字节序列)

5

我正在使用Haskell编写解析器,但是这个错误让我无法继续下去。以下是我的代码:

main = do
  arguments    <- getArgs
  let fileName = head arguments
  fileContents <- readFile fileName
  converter    <- open "UTF-8" Nothing
  let titleLength           = length fileName
      titleWithoutExtension = take (titleLength - 4) fileName
      allNonEmptyLines      = unlines $ tail $ filter (/= "") $ lines fileContents

当我尝试使用“US-ASCII”编码读取文件时,我遇到了著名的错误 hGetContents: invalid argument (invalid byte sequence)。我已经尝试通过将代码中的“UTF-8”更改为“US-ASCII”,但是错误仍然存在。是否有一种方法可以读取这些文件或解决任何类型的文件处理编码问题?

1个回答

7

您应该使用hSetEncoding来配置文件句柄以适应特定的文本编码,例如:

import System.Environment
import System.IO

main = do
  (path : _) <- getArgs
  h <- openFile path ReadMode
  hSetEncoding h latin1
  contents <- hGetContents h
  -- no need to close h
  putStrLn $ show $ length contents

如果您的文件包含非ASCII字符且不是UTF8编码,则latin1是一个不错的选择,尽管它并不是唯一的可能性。


只是好奇:为什么不需要关闭句柄?就在这个星期,我使用了 withFile,因为我认为它可以让我省去手动关闭句柄的步骤。 - somesoaccount
1
因为hGetContents会在你消耗完所有输入后关闭它。 - ErikR
@ErikR,现在我的程序可以工作了!谢谢。请问你能告诉我其他的可能性吗? - freinn
如果您的文件确实只包含字节,则可以将其读取为ByteString。另一方面,如果文件包含文本,则应使用编写内容时使用的编码。请参阅Unicode Encodings部分以获取可用编码列表。 - ErikR

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