c# - C# - .NET 4.7 - 流编码问题 - 不正确读取 unicode 和 ascii 字符
问题描述
我编写了一个小函数来将程序数据写入流。大概这个流可以去任何地方:到一个文件(当前用例),到一个套接字,到内存,任何地方。所以很自然地,我只是使用默认编码编写数据。经过一些测试,它引发了编码异常。所以我不得不将字符串编码成一个字节数组并写入字节。
但是有一个问题:写入的字节在读取时不会解码回相同的字符串。如果我们使用可在键盘上键入的 ascii 字符,这不是问题,但当我们开始使用 unicode 字符和显然是 27 个 ascii 字符时,它确实会成为问题。
这是测试用例。我鼓励你运行它:
using System.IO;
using System.Text;
using System;
public class TestCase
{
public static void Main(string[] args)
{
readwrite_tests();
}
public static void readwrite_tests()
{
string temps, result;
ulong count = 0;
byte[] buffer = new byte[sizeof(char) * 4];
using(MemoryStream mem = new MemoryStream(buffer))
using (BinaryReader reader = new BinaryReader(mem, Encoding.Default))
using (BinaryWriter writer = new BinaryWriter(mem, Encoding.Default))
{
for(char c = char.MinValue; c <= 0xfff; ++c)
{
temps = c.ToString();
if(mem.Position != 0) mem.Seek(0, SeekOrigin.Begin);
result = read_write(temps, writer, reader, mem);
if(!result.Equals(temps))
{
//Console.Write("char: " + c.ToString() + " int: " + ((int)c).ToString() +
// "\tread: " + result + " int: [");
//foreach (char d in result) Console.Write(((int)d).ToString() + " ");
//Console.WriteLine("]");
++count;
}
}
}
Console.WriteLine("Incorrect reads is " + count.ToString() +
" out of " + int.Parse("fff", System.Globalization.NumberStyles.HexNumber));
Console.WriteLine("Correct Reads: " + ((ulong)int.Parse("fff", System.Globalization.NumberStyles.HexNumber) - count));
}
public static string read_write(string s, BinaryWriter writer, BinaryReader reader, Stream stream)
{
string read_string = "";
byte[] bytes = Encoding.Default.GetBytes(s);
writer.Write(bytes.Length);
writer.Write(bytes);
stream.Seek(0, SeekOrigin.Begin);
try
{
read_string = Encoding.Default.GetString(reader.ReadBytes(reader.ReadInt32()));
}
catch(EndOfStreamException)
{
}
return read_string;
}
}
请在https://dotnetfiddle.net/上运行此程序以观察结果。
如您所见,我们只有 238 个正确读数。我不明白为什么会这样。让我知道是否可以提供更多信息,但我已经尝试了很多,包括改用 JsonSerializer(结果相同)。
解决方案
选择一个明确的编码并坚持下去。最好是 UTF-8。在 .NET 4.7.2 中,默认编码(至少在 .NET Fiddle 上)是西欧 (Windows)。在 .NET 5 中是 Unicode (UTF-8)。
如果您不相信我,请将此行添加到您的 read_write 例程中:
Console.WriteLine(Encoding.Default.EncodingName);
推荐阅读
- javascript - 将以下 Python 代码转换为基于 JavaScript 的 Google Apps 脚本代码
- docker - 变量不正确进入詹金斯 docker.inside()
- firebase - 如何将动态地图对象从 Firestore 映射到 Flutter 以及从 Flutter 到 Firestore?
- visual-studio - 为未处理的异常中断时使用的 Visual Studio 字体和颜色设置的名称?
- python - 如何使用 python 中的 Pmw 模块更改工具提示的颜色?
- python - 连续红色后获取熊猫值
- r - 如果满足条件并且字符串值包含在字符向量中,则在 R 中循环遍历行,将新列值设置为字符向量元素
- microservices - HTTP 存根服务器 stubby4j 是否支持带有附加查询参数设置的请求代理?
- node.js - 声明 edge-js 时 fs.existsSync 不是函数错误
- python - 嵌套 If/While/If 语句的问题