【问题标题】:Reading file with "US-ASCII" encoding in Haskell: hGetContents: invalid argument (invalid byte sequence)在 Haskell 中使用“US-ASCII”编码读取文件:hGetContents: invalid argument (invalid byte sequence)
【发布时间】:2016-02-08 01:59:00
【问题描述】:

我正在使用 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)。我试图通过“US-ASCII”更改我的代码中的“UTF-8”,但错误仍然存​​在。有没有办法读取这些文件,或者任何类型的文件处理编码问题?

【问题讨论】:

    标签: file haskell encoding io


    【解决方案1】:

    您应该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,因为我认为这样可以避免我手动关闭手柄。
    • 因为hGetContents 会在您消耗完所有输入后关闭它。
    • @ErikR 现在我的程序可以工作了!谢谢。请问您能告诉我其他的可能性吗?
    • 如果你的文件真的只包含字节,那么也许你应该把它当作一个字节串来读取。 OTOH,如果文件包含 text 您应该使用写入内容时使用的编码。有关可用编码的列表,请参阅Unicode Encodings 部分。
    猜你喜欢
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多