C#中的 Stream


  目錄:

什么是Stream?

什么是字節序列

Stream的構造函數

Stream的重要屬性及方法

Stream的示例

Stream異步讀寫

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的話,別忘了使用完流之后將其關閉

這個方法特別重要,使用完當前流千萬別忘記關閉!

 

 

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM