目錄:
Stream 和其子類的類圖
什么是Stream?
MSDN 中的解釋太簡潔了: 提供字節序列的一般視圖
(我可不想這么理解,這必定讓我抓狂,我理解的流是向自然界的河流那樣清澈而又美麗,c#中的流也是一樣,許多技術或者說核心技術都需要流的幫忙)
什么是字節序列呢?
字節對象都被存儲為連續的字節序列,字節按照一定的順序進行排序組成了字節序列
繼承Stream需要重寫自定義
public class MyStreamExample : Stream { public override bool CanRead { get { throw new NotImplementedException(); } } public override bool CanSeek { get { throw new NotImplementedException(); } } public override bool CanWrite { get { throw new NotImplementedException(); } } public override void Flush() { throw new NotImplementedException(); } public override long Length { get { throw new NotImplementedException(); } } public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override int Read(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } }
1:CanRead:只讀屬性,判斷該流是否能夠讀取
2:CanSeek:只讀屬性,判斷該流是否支持跟蹤查找
3:CanSeek:只讀屬性,判斷該流是否可寫
4:void Flush():
當我們使用流寫文件時,數據流會先進入到緩沖區中,而不會立刻寫入文件,當執行這個方法后,緩沖區的數據流會立即注入基礎流
MSDN中的描述:使用此方法將所有信息從基礎緩沖區移動到其目標或清除緩沖區,或者同時執行這兩種操作。根據對象的狀態,可能需要修
改流內的當前位置(例如,在基礎流支持查找的情況下即如此)當使用 StreamWriter 或 BinaryWriter 類時,不要刷新 Stream 基對象。
而應使用該類的 Flush 或 Close 方法,此方法確保首先將該數據刷新至基礎流,然后再將其寫入文件。
5:Length:表示流的長度
6:Position屬性
雖然從字面中可以看出這個Position屬性只是標示了流中的一個位置而已,可是我們在實際開發中會發現這個想法會非常的幼稚,
很多asp.net項目中文件或圖片上傳中很多朋友會經歷過這樣一個痛苦:Stream對象被緩存了,導致了Position屬性在流中無法
找到正確的位置,這點會讓人抓狂,其實解決這個問題很簡單,聰明的你肯定想到了,其實我們每次使用流前必須將Stream.Position
設置成0就行了,但是這還不能根本上解決問題,最好的方法就是用Using語句將流對象包裹起來,用完后關閉回收即可。
7:abstract int Read(byte[] buffer ,int offset ,int count)
這個方法包含了3個關鍵的參數:緩沖字節數組,位移偏量和讀取字節個數,每次讀取一個字節后會返回一個緩沖區中的總字節數
第一個參數:這個數組相當於一個空盒子,Read()方法每次讀取流中的一個字節將其放進這個空盒子中。(全部讀完后便可使用buffer字節數組了)
第二個參數:表示位移偏量,告訴我們從流中哪個位置(偏移量)開始讀取。
最后一個參數:就是讀取多少字節數。
返回值便是總共讀取了多少字節數.
8:abstract long Seek(long offset,Seek)
大家還記得Position屬性么?其實Seek方法就是重新設定流中的一個位置,在說明offset參數作用之前大家先來了解下SeekOrigin這個枚舉:
如果 offset 為負,則要求新位置位於 origin 指定的位置之前,其間隔相差 offset 指定的字節數。如果 offset 為零 (0),則要求新位置位於由 origin 指定的位置處。
如果 offset 為正,則要求新位置位於 origin 指定的位置之后,其間隔相差 offset 指定的字節數.
Stream. Seek(-3,Origin.End); 表示在流末端往前數第3個位置
Stream. Seek(0,Origin.Begin); 表示在流的開頭位置
Stream. Seek(3,Orig`in.Current); 表示在流的當前位置往后數第三個位置
查找之后會返回一個流中的一個新位置。其實說道這大家就能理解Seek方法的精妙之處了吧
*9: abstract void Write(byte[] buffer,int offset,int count)
這個方法包含了3個關鍵的參數:緩沖字節數組,位移偏量和讀取字節個數
和read方法不同的是 write方法中的第一個參數buffer已經有了許多byte類型
的數據,我們只需通過設置 offset和count來將buffer中的數據寫入流中
*10: virtual void Close()
關閉流並釋放資源,在實際操作中,如果不用using的話,別忘了使用完流之后將其關閉
這個方法特別重要,使用完當前流千萬別忘記關閉!