【问题标题】:Reading multi language text file in c#在 C# 中读取多语言文本文件
【发布时间】:2016-08-05 11:55:32
【问题描述】:

我必须阅读一个可以包含以下语言字符的文本文件:英语、日语、中文、法语、西班牙语、德语、意大利语

我的任务是简单地读取数据并将其写入新的文本文件(在 100 个字符后放置新行 char \n)。

我不能使用File.ReadAllTextFile.ReadAllLines,因为文件大小可能超过 500 MB。所以我写了以下代码:

using (var streamReader = new StreamReader(inputFilePath, Encoding.ASCII))
{
      using (var streamWriter = new StreamWriter(outputFilePath,false))
      {
           char[] bytes = new char[100];
           while (streamReader.Read(bytes, 0, 100) > 0)
           {
                 var data = new string(bytes);
                 streamWriter.WriteLine(data);
           }
           MessageBox.Show("Compleated");
       }
}

除了ASCII 编码我尝试过UTF-7UTF-8UTF-32IBM500。但是在读写多语言字符方面没有运气。

请帮助我实现这一目标。

【问题讨论】:

  • 语言无关紧要(如果你真的需要计算字符,也就是符号)。重要的是编码,这些特殊字符是如何存储的。如果编码使用 8 位来表示一个字符(ASCII),那么你的方法是可以的,因为读取 100 个字节等于读取 100 个字符:只需在写入每个部分后添加'\n'。否则(variable-lengh encoding)你确实有麻烦了,你一定知道/detect encoding
  • 您将不得不弄清楚文本是如何编码的。如果文件包含亚洲和西方语言,它可能是 Unicode、Big Endian Unicode 或 UTF32。希望该文件以 Christian Jäger 的回答中所示的编码指示符开头。或者它可能是编码的混合,在这种情况下,您必须弄清楚文件的结构。甚至可能您必须检查文本并推断编码,这根本不是一件容易的事。
  • 如果没有按照规范、约定或标准进行编码,一个选项是“发回”。 “检测”编码是最后的手段。
  • 我认为stackoverflow.com/questions/7470997/… 应该会有所帮助

标签: c# windows encoding .net-4.5.2


【解决方案1】:

您必须查看正在解析的文件的前 4 个字节。 这些字节将提示您必须使用什么编码。

这是我为完成任务而编写的辅助方法:

public static string GetStringFromEncodedBytes(this byte[] bytes) {
    var encoding = Encoding.Default;
    var skipBytes = 0;
        if (bytes[0] == 0x2b && bytes[1] == 0x2f && bytes[2] == 0x76) {
            encoding = Encoding.UTF7;
            skipBytes = 3;
        }
        if (bytes[0] == 0xef && bytes[1] == 0xbb && bytes[2] == 0xbf) {
            encoding = Encoding.UTF8;
            skipBytes = 3;
        }

        if (bytes[0] == 0xff && bytes[1] == 0xfe) {
            encoding = Encoding.Unicode;
            skipBytes = 2;
        }

        if (bytes[0] == 0xfe && bytes[1] == 0xff) {
            encoding = Encoding.BigEndianUnicode;
            skipBytes = 2;
        }
        if (bytes[0] == 0 && bytes[1] == 0 && bytes[2] == 0xfe && bytes[3] == 0xff) {
            encoding = Encoding.UTF32;
            skipBytes = 4;
        }


        return encoding.GetString(bytes.Skip(skipBytes).ToArray());
    }

【讨论】:

  • 这将如何处理英语日语中文法语西班牙语德语意大利语的字符
  • 它不会处理特定的字符,它会告诉你整个文件的编码。如果您有一个混合编码的字节流,您将需要检查流中是否存在编码开始,并使用检测到的编码处理流的其余部分(直到下一个编码开始)。如果您正在阅读的文件是完全混合的语言,而没有对使用的编码进行任何声明,对不起,我将无济于事
  • 虽然这可能是检测文件编码所必需的,但这不是一个完整的答案,因为它没有显示如何读取文件的其余部分。这可能就是为什么有人反对它。很容易添加一个示例,说明您如何使用这种方法读取整个文件。
【解决方案2】:

这是一个很好的开始,可以找到答案。如果 i 不等于 100,则需要读取更多字符。像 é 这样的法语字符没有问题 - 它们都在 C# char 类中处理。

char[] soFlow = new char[100];
int posn = 0;
using (StreamReader sr = new StreamReader("a.txt"))
   using (StreamWriter sw = new StreamWriter("b.txt", false))
      while(sr.EndOfStream == false)
      {
          try {
             int i = sr.Read(soFlow, posn%100, 100);
             //if i < 100 need to read again with second char array
             posn += 100;
             sw.WriteLine(new string(soFlow));
          }
          catch(Exception e){Console.WriteLine(e.Message);}
      } 

Spec: Read(Char[], Int32, Int32) 从当前流中读取指定的最大字符到缓冲区,从指定的索引开始。

当然对我有用:)

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2011-12-08
    • 1970-01-01
    • 2019-11-01
    • 2014-12-13
    • 2013-11-13
    相关资源
    最近更新 更多