在C#中处理非英文字符

时间:2012-08-24 04:13:50

标签: c# character-encoding streamreader streamwriter

我需要了解字符集和编码权限。有人能指出我在C#中处理不同的字符集吗?

这是我面临的一个问题 -

        using (StreamReader reader = new StreamReader("input.txt"))
        using (StreamWriter writer = new StreamWriter("output.txt")
        {
            while (!reader.EndOfStream)
            {
                writer.WriteLine(reader.ReadLine());
            }
        }

这个简单的代码段并不总是保留编码 -

例如 -

输入中的Aukéna在输出中变成了Auk�na。

4 个答案:

答案 0 :(得分:5)

您只有编码问题。你必须记住,你真正阅读的只是一串流。你必须告诉你的程序如何正确解释这些位。

要解决您的问题,只需使用采用编码的构造函数,并将其设置为文本使用的任何编码。

http://msdn.microsoft.com/en-us/library/ms143456.aspx

http://msdn.microsoft.com/en-us/library/3aadshsx.aspx

答案 1 :(得分:2)

我想在阅读文件时,您应该知道文件的编码方式。否则您很容易无法正确阅读。

当您知道文件的编码时,您可以执行以下操作:

        using (StreamReader reader = new StreamReader("input.txt", Encoding.GetEncoding(1251)))
        using (StreamWriter writer = new StreamWriter("output.txt", false, Encoding.GetEncoding(1251)))
        {
            while (!reader.EndOfStream)
            {
                writer.WriteLine(reader.ReadLine());
            }
        }

如果您想更改文件的原始编码,则会出现另一个问题。

以下文章可能会为您提供编码的良好基础: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

这是一篇msdn文章,您可以从中开始: Encoding Class

答案 2 :(得分:2)

StreamReader.ReadLine()尝试使用UTF编码读取文件。如果这不是您的文件使用的格式,StreamReader将无法正确读取字符。

This article详细说明了问题,并建议将构造函数传递给System.Text.Encoding.Default

答案 3 :(得分:0)

您始终可以创建自己的解析器。我用的是:

`var ANSI =(编码)Encoding.GetEncoding(1252).Clone();

ANSI.EncoderFallback = new EncoderReplacementFallback(string.Empty);`

第一行创建了Win-1252编码的克隆(因为我处理的数据库与Win-1252一起工作,你可能想要使用UTF-8或ASCII)。第二行 - 解析字符时 - 如果没有与原始字符等效的字符串,则返回空字符串。

在此之后,您希望最好过滤掉所有命令字符(根据您的需要,不包括制表符,空格,换行符和回车符。)

下面是我设置的个人编码解析器,用于纠正输入数据库的数据。

private string RetainOnlyPrintableCharacters(char c)
{
//even if the character comes from a different codepage altogether, 
//if the character exists in 1252 it will be returned in 1252 format.
    var ansiBytes = _ansiEncoding.GetBytes(new char[] {c});

    if (ansiBytes.Any())
    {
        if (ansiBytes.First().In(_printableCharacters))
        {
            return _ansiEncoding.GetString(ansiBytes);
        }
    }
    return string.Empty;
}

_ansiEncoding来自var ANSI =(编码)Encoding.GetEncoding(1252).Clone();使用后备值设置

如果ansiBytes不为空,则表示传入的特定字符有可用的编码,因此将其与所有可打印字符的列表进行比较,如果存在,则为可接受的字符,因此返回