为什么BinaryWriter会在流的开头添加乱码?你怎么避免它?

时间:2009-09-28 18:04:13

标签: c# .net filestream binarywriter

我正在调试将一个对象的片段写入文件的一些问题,我已经找到了打开文件并在其中写入“TEST”的基本情况。我是这样做的:

static FileStream fs;
static BinaryWriter w;
fs = new FileStream(filename, FileMode.Create);
w = new BinaryWriter(fs);

w.Write("test");

w.Close();
fs.Close();

不幸的是,这最终会在文件前面添加一个框,它看起来像这样:

TEST,正面有一个有趣的盒子。为什么会这样,我该如何避免呢?

编辑:它似乎没有在这里显示框,但它是看起来像胡言乱语的unicode角色。

9 个答案:

答案 0 :(得分:23)

根据MSDN

,它们不是字节顺序标记,而是长度前缀
public virtual void Write(string value);
  

将长度为前缀的字符串写入   [流]

如果您想从该点读取字符串,则需要该长度前缀。请参阅BinaryReader.ReadString()

其他

因为看起来你真的想要一个文件头检查器

  1. 这是一个问题吗?你读回长度前缀,以便对文件进行类型检查,确认它正常工作

  2. 您可以使用Encoding.ASCII将字符串转换为byte []数组。但是,你必须使用固定(隐含)长度或...自己前缀。读完byte []后,您可以再次将其转换为字符串。

  3. 如果您要编写大量文本,甚至可以将TextWriter附加到同一个流中。但要小心,作家想要关闭他们的流。我不会一般地建议这一点,但很高兴知道。在这里你也必须标记一个其他读者可以接管的点(固定标题工作正常)。

答案 1 :(得分:8)

那是因为BinaryWriter正在编写字符串的二进制表示,包括字符串的长度。如果你要写直接数据(例如byte []等),它将不包括该长度。

byte[] text = System.Text.Encoding.Unicode.GetBytes("test");
FileStream fs = new FileStream("C:\\test.txt", FileMode.Create);
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(text);
writer.Close();

你会注意到它不包括长度。如果您要使用二进制编写器编写文本数据,则需要先进行转换。

答案 2 :(得分:8)

开头的字节是字符串的长度,它被写成可变长度的整数。

如果字符串不超过127个字符,则长度将存储为一个字节。当字符串达到128个字符时,长度写为2,并且它将以一定的长度移动到3和4。

这里的问题是你正在使用BinaryWriter,它会写出BinaryReader稍后可以读回的数据。如果你想用自己的自定义格式写出来,你必须放弃这样的字符串,或者完全放弃使用BinaryWriter。

答案 3 :(得分:6)

正如Henk在this answer中指出的那样,这是字符串的长度(作为32位int)。

如果您不想这样,您可以通过将每个字母的ASCII字符写为字节来手动编写“TEST”,或者您可以使用:

System.Text.Encoding.UTF8.GetBytes("TEST")

并编写结果数组(不包含int长度)

答案 4 :(得分:2)

您所看到的实际上是一个7位编码的整数,这是一种integer compression BinaryWriter将文本添加到文本中,以便读者(即BinaryReader)知道写入的字符串有多长。

您可以在http://dpatrickcaldwell.blogspot.se/2011/09/7-bit-encoding-with-binarywriter-in-net.html了解有关此实施细节的更多信息。

答案 5 :(得分:0)

您可以将其保存为UTF8编码的字节数组,如下所示:

...

BinaryWriter w = new BinaryWriter(fs);

w.Write(UTF8Encoding.Default.GetBytes("test"));

...

答案 6 :(得分:-1)

这很可能是字节顺序标记。这是因为流的编码设置为Unicode。

答案 7 :(得分:-1)

请记住,Java字符串在内部以UTF-16编码。

所以,“test”实际上是由字节0xff,0xfe(一起是字节顺序标记),0x74,0x00,0x65,0x00,0x73,0x00,0x74,0x00组成的。

您可能希望使用字节而不是字符流。

答案 8 :(得分:-2)

听起来像字节顺序标记。

http://en.wikipedia.org/wiki/Byte-order_mark

也许你想把字符串写成UTF-8。