And*_*eld 3 encoding text haskell utf-16 utf
问题是 openFile 假定 UTF-8 并且句柄返回该编码作为编码。真正的问题是我正在获取(由学生)提交的以 UTF-16LE 编码的文件,我想要识别这些文件,因此我可以将它们转换为 UTF-8。这些文件实际上没有任何超出 ASCII 范围的内容,除了 BOM 标记(转换为 UTF-8 后会排序)。我尝试了以下方法:
fixFileEncoding fname =
do hdl <- openFile fname ReadMode
menc <- hGetEncoding hdl
hClose hdl
case menc of
Nothing -> system ("cp "++fname++" safe"++fname)
Just enc ->
do let encstr = show enc
putStrLn ("@@@@@@" ++ fname ++ " is "++encstr)
if take 6 encstr == "UTF-16"
then
system ("iconv -f UTF-16LE -t UTF-8 "++fname++" > safe"++fname)
else
system ("cp "++fname++" safe"++fname)
Run Code Online (Sandbox Code Playgroud)
无论文件的实际编码如何,“@@@@@”行都会报告 UTF-8。我通过使用 unixfile命令观察文件类型来验证这一点。
通常,您可以根据文件的生成方式了解文件的编码。有一些临时解决方案,例如 BOM,但它们仍然依赖于遵守这种格式的生产商。如果没有关于文件来源的先验知识(学生提交的文件就是这种情况),唯一的方法就是使用启发式方法。就是这样file。您还可以使用库bytestring和text在 Haskell 中实现一个简单的解决方案:
Data.ByteString.readFile,Data.Text.Encoding尝试使用一些猜测的编码(包含 UTF 编码)对其进行解码,为了解释您在尝试中观察到的结果,当您打开文件时,编码只是根据操作系统上的环境变量(特别是区域设置)猜测的,这就是为什么您总是得到相同的结果hGetEncoding。唯一openFile需要做的就是文件名,它没有足够的上下文来猜测文件的编码。