C#C# 温故而知新:Stream篇(—)

   3:  CanWrite: 只读属性,判断当前流是不是可写

     而应运用该类的 Flush 或 Close 方法,此办法确保率先将该多少刷新至基础流,然后再将其写入文件。

第三个参数:表示位移偏量,告诉大家从流中哪个地点(偏移量)开首读取。

的多少,大家只需经过设置 offset和count来将buffer中的数据写入流中

*10: virtual void Close()

C# 1C# 2

C# 3

 

Stream 类有一个protected 类型的构造函数,
可是它是个抽象类,不可以直接如下使用

 

那什么是字节种类呢?

可以见到系统活动帮大家落实了Stream 的肤浅属性和总体性方法

为了让我们可以很快了然和消化上述特性和方法我会写个示范并且主要部分会详细表明

*4: void Flush():这一点必须说得过细些:

 1 static void Main(string[] args)
 2         {
 3             byte[] buffer = null;
 4 
 5             string testString = "Stream!Hello world";
 6             char[] readCharArray = null;
 7             byte[] readBuffer = null;
 8             string readString = string.Empty;
 9             //关于MemoryStream 我会在后续章节详细阐述
10             using (MemoryStream stream = new MemoryStream()) 
11             {
12                 Console.WriteLine("初始字符串为:{0}", testString);
13                 //如果该流可写
14                 if (stream.CanWrite)
15                 {
16                     //首先我们尝试将testString写入流中
17                     //关于Encoding我会在另一篇文章中详细说明,暂且通过它实现string->byte[]的转换
18                     buffer = Encoding.Default.GetBytes(testString);
19                     //我们从该数组的第一个位置开始写,长度为3,写完之后 stream中便有了数据
20                     //对于新手来说很难理解的就是数据是什么时候写入到流中,在冗长的项目代码面前,我碰见过很
21                     //多新手都会有这种经历,我希望能够用如此简单的代码让新手或者老手们在温故下基础
22                     stream.Write(buffer, 0,3);
23 
24                     Console.WriteLine("现在Stream.Postion在第{0}位置",stream.Position+1);
25 
26                     //从刚才结束的位置(当前位置)往后移3位,到第7位
27                     long newPositionInStream =stream.CanSeek? stream.Seek(3, SeekOrigin.Current):0;
28 
29                     Console.WriteLine("重新定位后Stream.Postion在第{0}位置", newPositionInStream+1);
30                     if (newPositionInStream < buffer.Length)
31                     {
32                         //将从新位置(第7位)一直写到buffer的末尾,注意下stream已经写入了3个数据“Str”
33                         stream.Write(buffer, (int)newPositionInStream, buffer.Length - (int)newPositionInStream);
34                     }
35 
36                     
37                     //写完后将stream的Position属性设置成0,开始读流中的数据
38                     stream.Position = 0;
39 
40                     // 设置一个空的盒子来接收流中的数据,长度根据stream的长度来决定
41                     readBuffer = new byte[stream.Length];
42 
43 
44                     //设置stream总的读取数量 ,
45                     //注意!这时候流已经把数据读到了readBuffer中
46                     int count = stream.CanRead?stream.Read(readBuffer, 0, readBuffer.Length):0;
47          
48 
49                     //由于刚开始时我们使用加密Encoding的方式,所以我们必须解密将readBuffer转化成Char数组,这样才能重新拼接成string
50 
51                     //首先通过流读出的readBuffer的数据求出从相应Char的数量
52                     int charCount = Encoding.Default.GetCharCount(readBuffer, 0, count);
53                     //通过该Char的数量 设定一个新的readCharArray数组
54                     readCharArray = new char[charCount];
55                     //Encoding 类的强悍之处就是不仅包含加密的方法,甚至将解密者都能创建出来(GetDecoder()),
56                     //解密者便会将readCharArray填充(通过GetChars方法,把readBuffer 逐个转化将byte转化成char,并且按一致顺序填充到readCharArray中)
57                     Encoding.Default.GetDecoder().GetChars(readBuffer, 0, count, readCharArray, 0);
58                     for (int i = 0; i < readCharArray.Length; i++)
59                     {
60                         readString += readCharArray[i];
61                     }
62                     Console.WriteLine("读取的字符串为:{0}", readString);
63                 }
64 
65                 stream.Close();
66             }
67 
68             Console.ReadLine();
69 
70         }

据此我们自定义一个流继承自Stream 看看怎样属性必须重写或自定义:

以此艺术包涵了3个主要的参数:缓冲字节数组,位移偏量和读取字节个数

*6: Position属性:(万分关键)

当时进入正题,让我们来表达下c#的 Stream 是何等使用的

 1 public class MyStreamExample : Stream 
 2     {
 3 
 4         public override bool CanRead
 5         {
 6             get { throw new NotImplementedException(); }
 7         }
 8 
 9         public override bool CanSeek
10         {
11             get { throw new NotImplementedException(); }
12         }
13 
14         public override bool CanWrite
15         {
16             get { throw new NotImplementedException(); }
17         }
18 
19         public override void Flush()
20         {
21             throw new NotImplementedException();
22         }
23 
24         public override long Length
25         {
26             get { throw new NotImplementedException(); }
27         }
28 
29         public override long Position
30         {
31             get
32             {
33                 throw new NotImplementedException();
34             }
35             set
36             {
37                 throw new NotImplementedException();
38             }
39         }
40 
41         public override int Read(byte[] buffer, int offset, int count)
42         {
43             throw new NotImplementedException();
44         }
45 
46         public override long Seek(long offset, SeekOrigin origin)
47         {
48             throw new NotImplementedException();
49         }
50 
51         public override void SetLength(long value)
52         {
53             throw new NotImplementedException();
54         }
55 
56         public override void Write(byte[] buffer, int offset, int count)
57         {
58             throw new NotImplementedException();
59         }
60     }

若是 offset 为负,则须求新岗位位于 origin 指定的地点此前,其距离相差
offset 指定的字节数。尽管 offset 为零 (0),则必要新职责放在由 origin
指定的职位处。

实在不难的来了解的话字节连串指的是:

闭馆流并释放资源,在实际操作中,假如不用using的话,别忘了使用完流之后将其倒闭

MSDN 中的解释太不难了: 提供字节体系的一般视图

显示结果:

(卡其灰部分为机要请我们必须可以清楚,以往会在相应的章节中介绍)

   1:  CanRead: 只读属性,判断该流是不是可以读取:

   个系类的计算篇中

不可胜举asp.net项目粤语件或图表上传中广大朋友会经历过这么一个缠绵悱恻:Stream对象被缓存了,导致了Position属性在流中不可以

虽说从字面中可以观察这一个Position属性只是标志了流中的一个职分而已,不过大家在实际上花费中会发现这几个想法会格外的稚气,

 最终是有关c#中Stream类和其子类的类图

1 异步读取
2 public virtual IAsyncResult BeginRead(byte[] buffer,int offset,int count,AsyncCallback callback,Object state)
3 异步写
4 public virtual IAsyncResult BeginWrite( byte[] buffer, int offset, int count, AsyncCallback callback, Object state )
5 结束异步读取
6 public virtual int EndRead( IAsyncResult asyncResult ) 
7 结束异步写
8 public virtual void EndWrite( IAsyncResult asyncResult )

敬请期待!

    当我们使用流写文件时,数据流会先进入到缓冲区中,而不会立马写入文件,当执行这些方法后,缓冲区的数量流会即刻注入基础流

最终一个参数:就是读取多少字节数。

本条格局包蕴了3个重点的参数:缓冲字节数组,位移偏量和读取字节个数,每一遍读取一个字节后会回去一个缓冲区中的总字节数

C#,世家必要特别注意的是stream.Positon那一个很神奇的习性,在错综复杂的主次中,往往流对象操作也会很复杂,

 

(我可不想那样精通,那肯定让自家抓狂,我了然的流是向宇宙的河流那样清澈而又漂亮,c#中的流也是千篇一律,许多技巧恐怕说宗旨技术都要求流的相助)

文中很多知识点都以本人感悟学习而来,中午写文不易于,请我们多多关切下,下一章将会介绍操作流类的工具:StreamReader
和StreamWriter

Stream stream = new Stream();

*7: abstract int Read(byte[] buffer, int offset, int count)

那怎么有关流的表达可以抽象为下列处境:

率先个参数:这几个数组约等于一个空盒子,Read()方法每便读取流中的一个字节将其放进那几个空盒子中。(全体读完后便可使用buffer字节数组了)

倘使 offset 为正,则必要新岗位位于 origin 指定的职位然后,其距离相差
offset 指定的字节数.

     改流内的最近岗位(例如,在基础流帮忙查找的景观下即那样)当使用 StreamWriter 或 BinaryWriter 类时,不要刷新 Stream 基对象。

异步之后,那一个类似于阻塞难点会烟消云散,可知微软对于异步的支撑正在加大。

本章介绍了流的基本概念和c#中关于流的基类Stream所包括的局地最紧要的质量和艺术,关键是一对艺术和性质的底细和我们操作流对象时务必注意的事项,

  5: Length:表示流的长度

 
 为啥这几个在目录中是浅湖蓝的?其实本人个人认为那么些类图不应有放在那篇博文中,原因是我们实在清楚并熟稔操作了Stream的富有子类?(大牛除外)

小说来源:http://www.cnblogs.com/JimmyZheng/archive/2012/03/17/2402814.html\#no1

 

字节对象都被贮存为总是的字节序列,字节根据一定的逐条举行排序组成了字节体系

*9: abstract void Write(byte[] buffer,int offset,int count)

再次来到值便是一起读取了有些字节数.

检索之后会回去一个流中的一个新岗位。其实说道那大家就能清楚Seek方法的小巧之处了吗

什么是Stream?

实际并不复杂,(必须表达下 每回调用 Begin方法时都必须调用五遍 相对应的end方法)

C# 4C# 5

本章统计:

 
(那也是自己写后续文章的引力之一,写博能很好的晋升知识点的吸纳,不仅能帮衬别人,也能增长协调的对于知识点的知晓),所以我想把类图放在那

让我们一贯温故或上学下Stream类的布局,属性和相关办法

Stream. Seek(3,Orig`in.Current); 表示在流的日前岗位以往数第四个职位

   2:  CanSeek: 只读属性,判断该流是还是不是辅助跟踪查找

*8: abstract long Seek(long offset, SeekOrigin origin)

 

Stream. Seek(-3,Origin.End);  表示在流末端往前数第3个职责

 

在Stream基类中还有多少个根本措施,它们可以很好已毕异步的读写,

首先是构造函数

随即让大家的话下有关流中怎么落到实处异步操作

   
大家还记得Position属性么?其实Seek方法就是再度设定流中的一个职位,在认证offset参数功用从前我们先来询问下SeekOrigin那几个枚举:

大家很容易的就能发现前多个艺术完成了IAsyncResult接口,后2个end方法也符合带上了一个IAsyncResult参数,

和一般同步read或write方法同样的是,他们得以当作同步方法应用,可是在盘根错节的处境下大概也难逃阻塞崩溃等等,然而倘诺启用了

Stream. Seek(0,Origin.Begin); 表示在流的开第四地点

    
MSDN中的描述:使用此格局将有着新闻从基础缓冲区移动到其目的或免除缓冲区,恐怕同时实施那二种操作。依据指标的景色,只怕必要修

和read方法差其余是 write方法中的第二个参数buffer已经有了重重byte类型

找到正确的任务,那一点会令人抓狂,其实消除这么些标题很简短,聪明的你肯定想到了,其实大家每便使用流前必须将Stream.Position

设置成0就行了,不过那还不大概根本上消除难题,最好的章程就是用Using语句将流对象包裹起来,用完后关门回收即可。

C# 6

View Code

理所当然Stream.Close()咱们都懂的

View Code

  类图呢?大家自然会那样想把 ^^

一定要铭记在心将stream.Positon设置在你所必要的没错地点,还有就是
using语句的选拔,它会自动销毁stream对象,

以此格局特别首要,使用完当前流千万别忘记关闭!

打个比方:一条河中有一条鱼游过,那一个鱼就是一个字节,这几个字节包涵鱼的眸子,嘴巴,等构成8个二进制,显著那条河就是大家的骨干目的:流

 

相关文章