【发布时间】:2017-11-21 09:14:11
【问题描述】:
使用 C# 将字符串写入二进制文件时,长度(以字节为单位)会自动添加到输出之前。根据MSDN documentation,这是一个无符号整数,但也是一个单字节。他们给出的示例是单个 UTF-8 字符将是三个写入字节:1 个大小字节和 2 个字符字节。这适用于长度不超过 255 的字符串,并且与我观察到的行为相匹配。
但是,如果您的字符串长度超过 255 个字节,则无符号整数的大小会根据需要增加。举个简单的例子,假设 1024 个字符为:
string header = "ABCDEFGHIJKLMNOP";
for (int ii = 0; ii < 63; ii++)
{
header += "ABCDEFGHIJKLMNOP";
}
fileObject.Write(header);
导致字符串前有 2 个字节。创建一个 2^17 长度的字符串会产生一个有点令人抓狂的 3 字节数组。
因此,问题是如何知道要读取多少字节才能获得读取时后续内容的大小?我不一定知道 先验 标头大小。最后,我可以强制 Write(string) 方法始终使用一致的大小(比如 2 个字节)吗?
一种可能的解决方法是编写我自己的 write(string) 方法,但出于显而易见的原因,我想避免这种情况(类似的问题 here 和 here 接受这个作为答案)。另一个更容易接受的解决方法是让读者寻找一个特定的字符来开始 ASCII 字符串信息(可能是一个不可打印的字符?),但这并不是万无一失的。最后一种解决方法(我能想到的)是强制字符串在特定数量的大小字节的大小范围内;再说一遍,这并不理想。
虽然强制字节数组的大小保持一致是最简单的,但我可以控制阅读器,因此也欢迎任何聪明的阅读器解决方案。
【问题讨论】:
-
它使用variable-length 7-bit encoding。一个微优化,很少有理由为此生气。如果您不喜欢它,请考虑 Encoding.UTF8.GetBytes() 但不要忘记序列化 byte[] 数组的长度,以便您可以正确读取它。不要用7位编码,呵呵。
-
您确定长度在 128 到 255 之间的字符串实际上将长度存储为单个字节吗?
-
@MatthewWatson 我确定他们不是 :)
-
@AndyK。在该编码中,每个字节都有关于是否有另一个字节的信息(这就是它是 7 位编码的原因——最后一位用于那个)。因此,您读取 1 个字节,然后检查该位并决定是否需要读取下一个字节。这意味着您始终可以读取字符串长度,即使该长度是在可变长度数组中编码的。
-
@AndyK。这是
Read7BitEncodedInt的参考来源:referencesource.microsoft.com/#mscorlib/system/io/…
标签: c# string size binaryfiles