Stream.Write 与 StreamWriter.Write 的不同

Stream.Write 与 StreamWriter.Write 的不同

溪流。写作和流作者。Write是我们向流中写入数据时最常用的方法。下面将详细解释这两种方法。

第一,测试结果是否相同。先看下面两个代码:1是StreamWriter。写2是流。写:

1复制代码如下:Stream ms=new memory Stream();String=这是测试字符串;StreamWriter sw=新的StreamWriter(毫秒,编码。UTF8);西南。write(str);西南。flush();

2复制代码如下:Stream ms=new memory Stream();String=这是测试字符串;byte[] buffer=编码。UTF8 . GetBytes(str);ms.Write(缓冲区,0,缓冲区。长度);ms . Flush();

我们可以看到上面的流水号。写出来可读性更强。

但是两个代码执行后的ms是不是一样的结果?

首先,我们来看一下长度,并将其添加到代码的末尾。

复制代码如下:console . writeline( streamwriter . write:{ 0 } ,ms . length);控制台。WriteLine(Stream。写:{0} ,毫秒长度);执行结果如下:

读者们,看到这里你们有什么想法?

第二,深究原因。让我们继续深入研究这额外的3个字节。

在方法之后,添加以下代码以十六进制形式打印出MemoryStream的内容。

复制代码如下:ms . Position=0;byte[] bytes=新字节[毫秒长度];ms.Read(字节,0,字节。长度);foreach(以字节为单位的变量项){ Console。写(项。ToString( X2 ) );}控制台。WriteLine(字符串。空);重新执行的结果如下:

在这里,我们发现StreamWriter的输出。写的是EF BB BF的三个额外字节。

谷歌:额外的东西是字节顺序标记(英文:byte-order mark,BOM)

可以在维基百科中找到:

编码

表示(十六进制)

表示(十进制)

UTF-8

EF BB BF

239 187 191

UTF-16(大端)

FE FF

254 255

UTF-16(小端)

FF FE

255 254

UTF-32(大端)

00 00法郎

0 0 254 255

UTF-32(小端)

法国法郎

255 254 0 0

UTF-7

2b76和下列字节之一:[38 | 39 | 2B | 2F]

3 47 118和下列字节之一:[56 | 57 | 43 | 47]

en:UTF-1

F7 64 4C

247 100 76

en:UTF-EBCDIC

第73至66页

221 115 102 115

Unicode的标准压缩方案

FE FF

14 254 255

恩:BOCU-1

FB 28可能还有FF

21 238 40,后面可能还有255

好了,知道这个东西之后,我们需要知道在StreamWriter中是否可以通过代码控制不输出这个BOM。写?

三。找到解决方案,开始反编译方法StreamWriter。写:

猜测红框中的代码输出BOM信息。好,进去看看:

果然,在这里,如上面的红框所示,GetPreamble方法是获取编码后的字节序列,与我们之前找到的信息完全一致。

好,我们继续找这个haveWrittenPreamble。可以设置它,它在Init方法中。

用杯子,CanSeed没有set方法,Write之前的位置必须是0,所以结束了。

四。结论从以上结论,我们可以确定:

1.如果没有双方约定的BOM,可以使用流。编写方法来输出它,或者在使用StreamWriter时添加新的UTF8Encoding(false)参数。写

2.当有BOM时,我们可以完成StreamWriter的功能。通过获取GetPreamble和Stream进行写入。写

Stream.Write 与 StreamWriter.Write 的不同