当前位置: 移动技术网 > IT编程>开发语言>c# > Stream.Write 与 StreamWriter.Write 的不同

Stream.Write 与 StreamWriter.Write 的不同

2019年07月18日  | 移动技术网IT编程  | 我要评论
一、测试方法是否结果相同首先看下面两段代码1是streamwriter.write 2是stream.write: 1复制代码 代码如下:stream ms = new

一、测试方法是否结果相同
首先看下面两段代码1是streamwriter.write 2是stream.write:


1

复制代码 代码如下:

stream ms = new memorystream();
string str = "这是测试字符串";
streamwriter sw = new streamwriter(ms, encoding.utf8);
sw.write(str);
sw.flush();

2

复制代码 代码如下:

stream ms = new memorystream();
string str = "这是测试字符串";
byte[] buffer = encoding.utf8.getbytes(str); 
ms.write(buffer, 0, buffer.length);
ms.flush();

上面我们可以看到streamwriter.write的可读性更好一些。

但是这两段代码执行后的ms是否是相同的结果呢?

首先我们来看下长度吧,在代码最后分别加上

复制代码 代码如下:

console.writeline("streamwriter.write:{0}", ms.length);
console.writeline("stream.write:{0}", ms.length);

执行后结果如下:

各位看官,看到这里有何想法?

二、深究原因
下面继续深究一下这个多出来的3个字节

在方法后面都加上如下一段代码将memorystream的内容以十六进制的形式打印出来

复制代码 代码如下:

ms.position = 0;
byte[] bytes = new byte[ms.length];
ms.read(bytes, 0, bytes.length);
foreach (var item in bytes){
console.write(item.tostring("x2") + " ");
}
console.writeline(string.empty);

再次执行结果如下:

 

这里我们发现用streamwriter.write输出多出了ef bb bf这3个字节

google一下:多出来的这个玩意是 字节顺序记号(英语: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 fe ff 0 0 254 255
utf-32(小端序) ff fe 00 00 255 254 0 0
utf-7 2b 2f 76和以下的一个字节:[ 38 | 39 | 2b | 2f ] 43 47 118和以下的一个字节:[ 56 | 57 | 43 | 47 ]
en:utf-1 f7 64 4c 247 100 76
en:utf-ebcdic dd 73 66 73 221 115 102 115
en:standard compression scheme for unicode 0e fe ff 14 254 255
en:bocu-1 fb ee 28 及可能跟随着ff 251 238 40 及可能跟随着255

ok,了解了这个东西后我们就就需要知道在streamwriter.write中能否用代码控制不输出这个bom吗?

三、查找解决办法
开始反编译streamwriter.write这个方法:

大致猜测是红色方框的代码输出了bom信息,ok再进去看:

 

果然在这里,看上图红框处,getpreamble方法是获取编码的字节序列,和我们之前查到的信息完全一致。

好下面继续找这个havewrittenpreamble有没设置的可能,在init方法中找到了它的身影。

 

杯具了,canseed没有set方法,write之前的position肯定为0,至此结束。

四、结论
由上面的结论,我们可以确定:

1.如果双方协议无bom时,可以使用stream.write方法来输出,或者使用streamwriter.write时加入new utf8encoding(false)参数。

2.有bom时,我们可以通过getpreamble和stream.write来完成streamwriter.write的功能。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网