在 C# 中使用不同类型的编码方案的十六进制字节输出有什么区别?

What is the difference between hex bytes output using different types of encoding schemes in C#?

考虑以下 C# 代码

     int x = 126;
     string s = "126";
     FileStream fs = new FileStream("test.txt", FileMode.Create);
     StreamWriter sw = new StreamWriter(fs);
     sw.WriteLine(x);
     sw.WriteLine(s);

输出(存储在test.txt中的十六进制字节)是31 32 36 0D 0A 31 32 36 0D 0A

如果我对第 4 行进行更改:

StreamWriter sw = new StreamWriter(fs, Encoding.Unicode);

输出为:FF FE 31 00 32 00 36 00 0D 00 0A 00 31 00 32 00 36 00 0D 00 0A 00

谁能帮我解释一下逻辑。是否有任何关于不同编码方案及其在使用 C#

的文件系统中的行为的参考

我建议你阅读Joel Spolsky's excellent article on the subject of character sets and encodings。简而言之:

  • 一个文件就是一个字节序列。
  • 字符串是字符序列。
  • 一个字符集定义了一组字符并分配了一个唯一的代码点(一个代表字符的整数——注意"integer" 不一定是每个字符的 int)。
  • 当你想在文件中存储一个字符串时,你需要将字符序列转换成字节序列。对于256个字符以下的字符集,通常字符和字节是一一对应的,但是对于更大的字符集,比如Unicode,就变得复杂了。
  • 编码 定义字符串字符的代码点应如何转换为字节。

因此,当您更改编码时,相同的字符串会被翻译成不同的字节序列。

请注意,字符集和编码的行为与编程语言无关。改变的是您如何引用和使用各种编码和字符集(通常,编码与特定字符集相关联,因此 select 编码也将隐式 select 字符集) .在 C# 的例子中,Encoding.Unicode 的命名很糟糕——它是 Unicode 字符集,但是 UTF-16LE encoding(其中每秒byte 将是 00 如果你只使用英文字符)。

此外,请注意,字符串在程序内部表示为 char 数组,其中每个 char 是一个值,表示来自 UTF-16 编码的两个后续字节(因此一些花哨的字符实际上可能表示为两个 char 值)。您无法直接访问该数组,并且大多数字符串功能都试图抽象掉这一事实。这种内部编码不会影响字符串如何写入文件(或者,您 select 手动编码,或者您获得您正在调用的操作的默认字符集 - StreamWriter 是 UTF -8(感谢@xanatos 的更正)。