在 .NET Framework 中使用 UNICODE 编码时,我需要您的帮助来解决困扰我的问题...
我必须与一些非 UNICODE 应用程序的客户数据系统交互,这些客户拥有全球公司(中国、韩国、俄罗斯……)。所以他们必须为我提供一个 ASCII 8 位文件,它将使用他们的 Windows 代码页进行编码。
因此,如果一位希腊客户向我发送一个产品名称中包含“Σ”(sigma 字母“\u03A3”)的文本文件,我将得到一个对应于 211 ANSI 代码点的等效字母,在我自己的代码页中表示。我的电脑是法文 Windows,这意味着代码页是 Windows-1252,所以我将在此文本文件中放置 'Ó'... 好的。
我知道这个客户是希腊人,所以我可以通过在我的导入参数中强制使用 windows-1253 代码页来读取他的文件。
/// <summary>
/// Convert a string ASCII value using code page encoding to Unicode encoding
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUnicode(string value, int codePage)
{
Encoding windows = Encoding.Default;
Encoding unicode = Encoding.Unicode;
Encoding sp = Encoding.GetEncoding(codePage);
if (sp != null && !String.IsNullOrEmpty(value))
{
// First get bytes in windows encoding
byte[] wbytes = windows.GetBytes(value);
// Check if CodePage to use is different from current Windows one
if (windows.CodePage != sp.CodePage)
{
// Convert to Unicode using SP code page
byte[] ubytes = Encoding.Convert(sp, unicode, wbytes);
return unicode.GetString(ubytes);
}
else
{
// Directly convert to Unicode using windows code page
byte[] ubytes = Encoding.Convert(windows, unicode, wbytes);
return unicode.GetString(ubytes);
}
}
else
{
return value;
}
}
好吧,最后我在我的应用程序中得到了“Σ”,我可以将它保存到我的 SQL Server 数据库中。现在我的应用程序必须执行一些复杂的计算,然后我必须通过自动导出将此文件返回给客户......
所以我的问题是我必须执行 UNICODE => ANSI 转换?!但这并不像我一开始想的那么简单……
我不想保存导入时使用的代码页,所以我的第一个想法是将UNICODE转换为windows-1252,然后自动将文件发送给客户。他们将使用自己的代码页读取导出的文本文件,所以这个想法对我来说很有趣。
但问题是这种方式的转换有一个奇怪的行为......这里有两个不同的例子:
第一个例子(я)
char ya = '\u042F';
string strYa = Char.ConvertFromUtf32(ya);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1251 = System.Text.Encoding.GetEncoding(1251);
string strYa1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strYa)));
string strYa1251 = ansi1251.GetString(System.Text.Encoding.Convert(unicode, ansi1251, unicode.GetBytes(strYa)));
所以strYa1252包含 ' ?',而strYa1251包含有效的字符 ' я '。因此,如果没有向 Convert() 函数指示有效的代码页,似乎不可能转换为 ANSI ... 所以 Unicode Encoding 类中没有任何内容可以帮助用户获得 ANSI 和 UNICODE 代码点之间的等价性?:\
第二个例子(Σ)
char sigma = '\u3A3';
string strSigma = Char.ConvertFromUtf32(sigma);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1253 = System.Text.Encoding.GetEncoding(1253);
string strSigma1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strSigma)));
string strSigma1253 = ansi1253.GetString(System.Text.Encoding.Convert(unicode, ansi1253, unicode.GetBytes(strSigma)));
此时,我在strSigma1253字符串中有正确的 ' Σ ' ,但我也有strSigma1252的' S ' 。如开头所述,如果找到 ANSI 代码,我应该有“ Ó ”,或者“?” 如果尚未找到该字符,但不是“S”。为什么?是的,当然,语言学家可以说“S”相当于希腊语 Sigma 字符,因为它们在两个字母表中听起来相同,但它们没有相同的 ANSI 代码!
那么 .NET 框架中的 Convert() 函数如何管理这种等价性呢?
有人有想法在我必须发送给客户的文本文件中从 UNICODE 写回 ANSI 字符吗?