C#UNICODE到ANSI的转换
在.NET Framework中使用UNICODE编码时,我需要您的帮助来解决一些困扰我的问题 我必须使用非UNICODE应用程序与一些客户数据系统进行接口,这些客户拥有全球公司(中国、韩国、俄罗斯等)。因此,他们必须向我提供一个ASCII 8位文件,该文件将使用Windows代码页进行编码 因此,如果希腊客户向我发送一个文本文件,其中包含产品名称中的∑(sigma字母'\u03A3'),我将得到一个对应于211 ANSI代码点的等效字母,在我自己的代码页中表示。我的电脑是法国Windows,这意味着代码页是Windows-1252,所以我会在这个文本文件中放置“Ó”。。。嗯 我知道这个客户是希腊客户,所以我可以通过强制导入参数中的windows-1253代码页来读取他的文件C#UNICODE到ANSI的转换,c#,unicode,ansi,C#,Unicode,Ansi,在.NET Framework中使用UNICODE编码时,我需要您的帮助来解决一些困扰我的问题 我必须使用非UNICODE应用程序与一些客户数据系统进行接口,这些客户拥有全球公司(中国、韩国、俄罗斯等)。因此,他们必须向我提供一个ASCII 8位文件,该文件将使用Windows代码页进行编码 因此,如果希腊客户向我发送一个文本文件,其中包含产品名称中的∑(sigma字母'\u03A3'),我将得到一个对应于211 ANSI代码点的等效字母,在我自己的代码页中表示。我的电脑是法国Windows,这
/// <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;
}
}
因此strYa1252包含“?”,而strYa1251包含有效字符“Ø”。所以,如果没有向convert()函数指示有效的代码页,似乎无法将te转换为ANSI。。。所以Unicode编码类中的任何内容都不能帮助用户获得ANSI和Unicode代码点之间的等价性:\
第二个示例(∑)
此时,我在strSigma1253字符串中有正确的“符号∑”,但在strSigma1252中也有“S”。如开头所示,如果已找到ANSI代码,则应使用“Ó”;如果未找到字符,则应使用“?”,但不使用“S”。为什么?
当然,语言学家可能会说“S”相当于希腊西格玛字符,因为它们在两个字母表中的发音相同,但它们没有相同的ANSI代码
那么.NET framework中的Convert()函数如何管理这种等价性呢
是否有人有想法将UNICODE中的ANSI字符写回我必须发送给客户的文本文件中
如果没有找到字符,我应该…“?”,但不是“S”。为什么?
这被称为“最佳匹配”编码,在大多数情况下,这是一件坏事。当Windows无法将字符编码到目标代码页时(因为代码页1252中不存在∑
),它会尽最大努力将字符映射到与之类似的内容。这可能意味着失去变音符号(ë
→e
),或映射到同源(∑
→S
),一个相关的字符(≤代码>→=
),一个不相关但看起来有点相似的字符(∞代码>→<代码>8),或其他任何疯狂的替代品在当时似乎是个好主意,但在实践中却被证明是文化上或数学上的冒犯
您可以看到cp1252的表格,包括Sigma映射
除了是一个可疑的用途无声的混乱,它也有一些。您应该能够通过设置为ReplacementFallback
或ExceptionFallback
来阻止这种情况的发生
是否有人有想法将UNICODE中的ANSI字符写回我必须发送给客户的文本文件中
您必须为每个客户保留一个编码表。使用该编码读取其输入文件进行解码;使用相同的编码写入它们的输出文件
(为了安全起见,请将新客户设置为UTF-8,并记录这是首选编码。)在将文本转换回客户的代码页之前,您确实需要了解客户的代码页。如果您没有这些信息,您将无法执行此操作。例如,如果您查看有关windows-1252代码页的MSDN(),此页底部有一个ANSI 1252代码和UNICODE代码点之间关系的列表。。。。所以我认为从UNICODE到一个或多个ANSI代码页是等价的?例如,所有windows代码页都有对应于sigma的所有代码……最好让您的客户自己使用UTF-8或Unicode。你也控制他们使用的软件吗?一点也不,这就是问题所在:P我们只为我们的应用程序和他们的应用程序提供接口,这些接口通常是一些旧的“自制”(非UNICODE)工业软件。。。。如果解决方案是将客户迁移到一些工业UTF8应用程序,我想我不会发布这个问题。^^我真的需要通过返回ASCII 8位文件来确保与他们的系统的兼容性……没有8位ASCII之类的东西。因此,您必须知道要保存到哪个代码页。
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)));
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)));