当前位置:  编程技术>.net/c#/asp.net

Stream.Write 与 StreamWriter.Write 的不同

    来源: 互联网  发布时间:2014-10-19

    本文导语:  一、测试方法是否结果相同首先看下面两段代码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 = ne...

一、测试方法是否结果相同
首先看下面两段代码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-8(大端序) FE FF 254 255 utf-8(小端序) 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的功能。


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间javax.xml.stream类xmloutputfactory成员方法: createxmleventwriter定义参考
  • Stream软件开发包 Stream SDK
  • java命名空间javax.xml.stream类xmloutputfactory成员方法: createxmlstreamwriter定义参考
  • 开源流媒体平台 Stream-2-Stream
  • java命名空间java.io接口objectstreamconstants的类成员方法: stream_version定义及介绍
  • Android-video-stream-rotation
  • java命名空间java.io接口objectstreamconstants的类成员方法: stream_magic定义及介绍
  • stream file的疑問?
  • java命名空间javax.xml.stream.events接口characters成员方法: iscdata定义参考
  • stream.h
  • java命名空间javax.xml.stream接口xmlstreamwriter成员方法: writeemptyelement定义参考
  • 关于IO Stream Chain的问题。 iis7站长之家
  • java命名空间javax.sql.rowset类baserowset的类成员方法: ascii_stream_param定义及介绍
  • 关于IO Stream Chain的问题。
  • java命名空间javax.print类docflavor.input_stream的类成员方法: pdf定义及介绍
  • C# Stream 和 byte[] 之间的转换
  • java命名空间javax.print类docflavor.input_stream的类成员方法: postscript定义及介绍
  • FILE* stream fread fwrite 的使用方法
  • java命名空间javax.print类docflavor.input_stream的类成员方法: gif定义及介绍
  • 一个新的JavaScript数据结构 stream.js
  • java命名空间javax.print类docflavor.input_stream的类成员方法: png定义及介绍
  • 如何理解JAVA中的stream?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3