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

Chr*_*ris 14 .net c# 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();
Run Code Online (Sandbox Code Playgroud)

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

测试,前面有一个有趣的盒子.这是为什么,我该如何避免呢?

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

Hen*_*man 23

根据MSDN,它们不是字节顺序标记,而是长度前缀:

public virtual void Write(string value);
Run Code Online (Sandbox Code Playgroud)

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

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

额外

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

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

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

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


Jos*_*hua 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();
Run Code Online (Sandbox Code Playgroud)

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


ang*_*son 8

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

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

这里的问题是你正在使用BinaryWriter,它会写出BinaryReader稍后可以读回的数据.如果您希望以自己的自定义格式书写,则必须删除这样的字符串,或者完全使用BinaryWriter.


Jon*_*n B 6

正如Henk在这个答案中指出的那样,这是字符串的长度(作为32位int).

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

System.Text.Encoding.UTF8.GetBytes("TEST")
Run Code Online (Sandbox Code Playgroud)

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