溪流。写作和流作者。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进行写入。写