使用 .NET 如何将包含 Latin-1 重音字符的 ISO 8859-1 编码文本文件转换为 UTF-8

Posted

技术标签:

【中文标题】使用 .NET 如何将包含 Latin-1 重音字符的 ISO 8859-1 编码文本文件转换为 UTF-8【英文标题】:Using .NET how to convert ISO 8859-1 encoded text files that contain Latin-1 accented characters to UTF-8 【发布时间】:2011-02-05 10:19:22 【问题描述】:

我收到了以ISO 88591-1 格式保存的文本文件,其中包含来自Latin-1 范围的重音字符(以及正常的ASCII a-z 等)。如何使用 C# 将这些文件转换为 UTF-8,以便 ISO 8859-1 中的单字节重音字符成为有效的 UTF-8 字符?

我尝试使用带有 ASCIIEncoding 的 StreamReader,然后通过实例化编码 ascii 和编码 utf8 然后使用 Encoding.Convert(ascii, utf8, ascii.GetBytes( asciiString) ) 将 ASCII 字符串转换为 UTF-8 — 但重音字符被呈现为问题标记。

我错过了什么步骤?

【问题讨论】:

您是否尝试过使用带有 UTF8 编码的 StreamWriter 将 asciiString 写入文本文件?这样做可以吗? @Task:他的问题是他永远无法从 8859-1 中取出字符串,而不是他无法将其保存为 UTF-8。 哦,这完全是他的问题,毫无疑问。我只是发现使用 StreamReader/StreamWriter 对(因此我可以看到输入/输出文件)而不是使用 Encoding.Convert 调用来调试文本转换更容易。那可能只是我。 @Task:我同意(因此我的回答!);) 【参考方案1】:

您需要获取正确的Encoding 对象。 ASCII 顾名思义:ASCII,意思是它只支持 7 位 ASCII 字符。如果您要做的是转换文件,那么这可能比直接处理字节数组更容易。

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName,
                                       Encoding.GetEncoding("iso-8859-1")))

    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(
                                           outFileName, Encoding.UTF8))
    
        writer.Write(reader.ReadToEnd());
    

但是,如果您想自己拥有字节数组,使用Encoding.Convert 很容易。

byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
    Encoding.UTF8, data);

在这里需要注意的是,如果你想走这条路,那么你应该使用基于编码的字符串阅读器,如StreamReader 来处理你的文件 IO。 FileStream 会更合适,因为它会读取文件的实际字节。

为了充分探索这个问题,这样的事情会起作用:

using (System.IO.FileStream input = new System.IO.FileStream(fileName,
                                    System.IO.FileMode.Open, 
                                    System.IO.FileAccess.Read))

    byte[] buffer = new byte[input.Length];

    int readLength = 0;

    while (readLength < buffer.Length) 
        readLength += input.Read(buffer, readLength, buffer.Length - readLength);

    byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
                       Encoding.UTF8, buffer);

    using (System.IO.FileStream output = new System.IO.FileStream(outFileName,
                                         System.IO.FileMode.Create, 
                                         System.IO.FileAccess.Write))
    
        output.Write(converted, 0, converted.Length);
    

在本例中,buffer 变量以byte[] 形式填充文件中的实际数据,因此不进行任何转换。 Encoding.Convert 指定源和目标编码,然后将转换后的字节存储在名为...converted 的变量中。然后直接将其写入输出文件。

就像我说的,第一个选项使用StreamReaderStreamWriter 会更简单,如果这就是你所做的一切,但后一个例子应该给你更多关于实际情况的提示。

【讨论】:

感谢大家的帮助,尤其是@Adam 的彻底回答【参考方案2】:

如果文件相对较小(例如,约 10 兆字节),您只需要两行代码:

  string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1"));
  System.IO.File.WriteAllText(outPath, txt);

【讨论】:

为什么你的解决方案只有在读取的文件小于 10 兆字节时才有效?

以上是关于使用 .NET 如何将包含 Latin-1 重音字符的 ISO 8859-1 编码文本文件转换为 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章

如何从 .NET 中的字符串中删除变音符号(重音符号)?

如何从 .NET 中的字符串中删除变音符号(重音符号)?

如何使用 JavaApi 将 XML 中的重音字符写入 MarkLogic?

在 Python 中,如何对包含重音符号的数据框进行排序?

使用带有无效字符的 Net::FTP gettextfile (ASCII-8BIT vs UTF-8)

无法使用php读取数组中的重音名称[重复]