【问题标题】:C# encoding conversion to UTF-8 - different behavior on Windows 7 vs. Windows Server 2008 R2?C# 编码转换为 UTF-8 - Windows 7 与 Windows Server 2008 R2 上的不同行为?
【发布时间】:2013-03-27 22:12:16
【问题描述】:

在将编码转换为 UTF-8 时,我在 Windows 平台之间遇到了一些奇怪的行为。如果我有一个带有“扩展 ASCII”字符的字符串,比如商标符号的字符 0x99,我可以在 Windows 7 上使用以下代码对其进行转换:

using System.Text;
...
string DefaultEncodedStr = <<Some string with Extended ASCII chars like 0x99 for TM>>
byte[] DefaultEncodedBytes = Encoding.Default.GetBytes(DefaultEncodedStr);
byte[] UTF8EncodedBytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, DefaultEncodedBytes);
char[] UTF8Chars = new char[Encoding.UTF8.GetCharCount(UTF8EncodedBytes, 0, UTF8EncodedBytes.Length)];
UTF8.GetChars(UTF8EncodedBytes, 0, UTF8EncodedBytes.Length, UTF8Chars, 0);
string UTF8Str = new string(UTF8Chars); 

但是,此代码无法在 Windows Server 2008 R2 上转换初始字符串 - “扩展 ASCII”字符仍存在于最终字符串中。

但是,此代码在 Windows Server 2008 R2 上运行:

using System.Text;
...
string DefaultEncodedStr = <<Some string with Extended ASCII chars like 0x99 for TM>>
byte[] DefaultEncodedBytes = Encoding.Default.GetBytes(DefaultEncodedStr)
string UTF8Str = Encoding.UTF8.GetString(DefaultEncodedBytes); 

但是,此代码无法在 Windows 7 上转换字符串!!

什么给了?为什么我看到使用相同内核基础 (Win7) 的桌面类和服务器类操作系统之间的行为不同?我真的需要包含某种平台检测代码来确定如何正确处理编码转换吗??

【问题讨论】:

  • 它是如何失败的?结果是不正确的,还是有异常?如果是前者,你期待什么?如果是后者,是什么样的异常,它说明了什么?
  • 如果您提供一个示例问题字符串会很有帮助,这样人们就可以复制粘贴进行测试。
  • 安装不同语言包的机器有区别吗?
  • 你想做什么?您没有转换编码 - 字符串就是字符串。没有 UTF-8 字符串或 ASCII 字符串之类的东西。字符串没有编码语义。
  • 既然Encoding.DefaultAn encoding for the operating system's current ANSI code page. 你可能有两台不同配置的机器的问题,不是吗?

标签: c# windows-7 encoding utf-8 windows-server-2008-r2


【解决方案1】:

.NET 字符串是 Unicode 字符序列。如果你有一个字符串

string s = "™";

那么字符串由 Unicode U+2122 TRADE MARK SIGN 字符组成。

所以,等效地你可以写

string s = "\u2122";

您可以使用编码将此字符序列转换为字节序列。

一种编码是 UTF-8:

byte[] bytes = Encoding.UTF8.GetBytes(s);
// bytes == { 0xE2, 0x84, 0xA2 }

另一种编码是 Windows-1252:

byte[] bytes = Encoding.GetEncoding("Windows-1252").GetBytes(s);
// bytes == { 0x99 }

所以,如果你有一个字节序列,它代表 Windows-1252 中的一个字符串,并且由字节 0x99 组成,你可以将它解码为一个字符串,如下所示:

string result = Encoding.GetEncoding("Windows-1252").GetString(bytes);
// result == "™"

Encoding.Default 返回操作系统的默认编码。这可能是 Windows-1252,但不是必须的。始终明确指定要使用的编码。

不同的计算机可以使用不同的编码作为默认编码,甚至可以在一台计算机上更改默认编码。因此,从一台计算机流式传输到另一台计算机甚至在同一台计算机上不同时间检索的数据可能会被错误地转换。

另见:

【讨论】:

  • 这个。我还想提一下,没有 X 字符这样的东西,其中 X 是编码或字符集。字符并不完全属于字符集。例如,™ 包含在 20 多种不同的字符集中。
  • 好的,这是有道理的。我最初得到的字符串显然已被“硬编码”到 Windows-1252,但基本操作系统仅通过使用 Encoding.Default 并不知道这一点,因此我必须指示系统将初始字符串假定为 Windows-1252 .谢谢!
  • 字符串没有编码!!只有表示字符串的字节序列才可以。
猜你喜欢
  • 2011-08-29
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2013-04-22
  • 2012-11-11
  • 1970-01-01
  • 2012-06-05
相关资源
最近更新 更多