天天看點

3-8 讀寫記憶體流

u<b>本節學習目标:</b>

n了解讀寫記憶體流MemoryStream的特點

n學習如何建立記憶體流MemoryStream

n了解讀寫緩存流BufferedStream

n學習如何建立緩存流BufferedStream

前面第二節,介紹了檔案流類FileStream,本節要繼續介紹其他流。那麼什麼是流?在.net程式中,涉及的輸入和輸出都是通過流來實作的。流是串行化裝置的抽象表示,流以讀/寫位元組的方式從存儲器讀/寫資料。存儲器是存儲媒介,磁盤或記憶體都是存儲器。正如除磁盤外還存在着多種存儲器,除檔案流之外也存在多種流,例如:網絡流、記憶體流、緩存流等。類Stream及其派生類組成流的家族。如圖3-12所示:

圖3-12  流家族類關系圖

所有流的類都是從類Stream派生出來的。類Stream是所有流的抽象基類,是以它不能被執行個體化為對象,隻能通過變量引用派生類的對象。Stream變量所引用對象具有一下一種或多種功能:

n讀:通過Read()或ReadByte()方法實作讀資料;

n寫:通過Write()或WriteByte()方法實作寫資料;

n定位:通過Position屬性和Seek()方法實作定位。

<b></b><b></b> 

<b>注意:</b>

派生的流對象隻能支援這些功能中的一部分。例如:NetworkStream不支援定位。可以利用從Stream派生出來的對象的CanRead、CanWrite和CanSeek屬性判斷流對象支援哪些操作。

另外,對于類MemoryStream,有兩點需要說明:

n對記憶體而不是對磁盤進行資料讀寫;

n減少了對臨時緩沖區和檔案的需要。

而對于類BufferedStream,有四點需要說明:

n對緩沖區進行資料讀寫;

n允許作業系統建立自己的緩沖區;

n輸入/輸出效率高且速度更快;

n在網絡通訊的時候經常會使用到。

類MemoryStream建立這樣的流,該流以記憶體而不是磁盤或網絡連接配接作為支援存儲區。類MemoryStream封裝以無符号位元組數組形式存儲的資料,該數組在建立MemoryStream對象時被初始化,或者該數組可建立為空數組。可在記憶體中直接通路這些封裝的資料。記憶體流可降低應用程式中對臨時緩沖區和臨時檔案的需要。

 FileStream對象與MemoryStream對象有很大差別,主要展現在以下方面:

nFileStream對象的資料來自檔案,而MemoryStream對象的資料來自記憶體緩沖區。這兩個類都繼承自Stream類。

nMemoryStream的資料來自記憶體中的一塊連續區域,這塊區域稱為“緩沖區(Buffer)”。可以把緩沖區看成一個數組,每個數組元素可以存放一個位元組的資料。

n在建立MemoryStream對象時,可以指定緩沖區的大小,并且可以在需要的時候更改。

    類MemoryStream的構造函數有7種重載,我們這裡重點介紹三種,如表3-16所示:

表3-16 類MemoryStream的常用構造函數

<b>名稱</b>

<b>說明</b>

MemoryStream ()

使用初始化為零的可擴充容量初始化 MemoryStream 類的新執行個體。

MemoryStream (byte[])

基于指定的位元組數組初始化 MemoryStream 類的無法調整大小的新執行個體。

MemoryStream (byte[], Boolean)

使用按指定要求設定的 CanWrite 屬性基于指定的位元組數組初始化 MemoryStream 類的無法調整大小的新執行個體。

    記憶體流對象還有一些重要的屬性。其中Length屬性代表了記憶體流對象存放的資料的真實長度,而Capacity屬性則代表了配置設定給記憶體流的記憶體空間大小。可以使用位元組數組建立一個固定大小的MemoryStream。

n<b>小實驗1:</b>

<b></b> 

MemoryStream mem = new MemoryStream(buffer);

//這時,無法再設定Capacity屬性的大小。

n<b>小實驗2:</b>

MemoryStream mem = new MemoryStream(buffer, false);

//這時,CanWrite屬性就被設定為false 。

這樣在記憶體流對象被執行個體化時,一些屬性就被影響了。

本案例您将學習到:如何通過使用記憶體流的屬性、方法來擷取記憶體流的占用空間資訊及改變記憶體流空間大小。

u實驗步驟(1):

由圖3-13所示,從工具箱之中拖拽五個Label控件到Form窗體上,拖拽一個Button控件。

圖3-13  MemoryStream類案例界面圖

u實驗步驟(2):

用滑鼠輕按兩下所有Button控件,進入.cs檔案編輯狀态準備進行開發。代碼加下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.IO;

namespace FileOptionApplication

{

    public partial class Form14 : Form

    {

        public Form14()

        {

            InitializeComponent();

        }

        //建立位元組數組

        byte[] buffer = new byte[600];

        /// &lt;summary&gt;

        /// 擷取測試性資料

        /// &lt;/summary&gt;

        private void GetTestData()

            for (int i = 0; i &lt; 600; i++)

            {

                buffer[i] = (byte)(i % 256);

                //byte類型的數最大不能超過255,用256取模實作

            }

        /// button1按鈕的滑鼠單擊Click事件

        private void button1_Click(object sender, EventArgs e)

            //建立測試資料

            GetTestData();

            //建立記憶體流對象,初始配置設定50位元組的緩沖區

            MemoryStream mem = new MemoryStream(50);

            //向記憶體流中寫入位元組數組的所有資料

            mem.Write(buffer,0,buffer.GetLength(0));

            //使用從緩沖區讀取的資料将位元組塊寫入目前流。

            //參數:

            //1、buffer從中寫入資料的緩沖區。

            //2、offset buffer中的位元組偏移量,從此處開始寫入。

            //3、count最多寫入的位元組數。

            //GetLength(0) 為 GetLength 的一個示例,它傳回 Array 的第一維中的元素個數。

            label1.Text = "寫入資料後的記憶體流長度是:"+mem.Length.ToString();

            label2.Text = "配置設定給記憶體流的緩沖區大小:"+mem.Capacity.ToString();

            mem.SetLength(500);

            label3.Text = "調用SetLength方法後的記憶體流長度:" + mem.Length.ToString();

            mem.Capacity = 620;//注意:此值不能小于Length屬性

            label4.Text = "調用Capacity方法後緩沖區大小:" + mem.Capacity.ToString();

            //将讀寫指針移到距流開頭10個位元組的位置

            mem.Seek(45, SeekOrigin.Begin);

            label5.Text = "記憶體中的資訊是:"+mem.ReadByte().ToString();

    }

}

u實驗步驟(3):

調試、運作程式,得到效果如圖3-14所示:

圖3-14  MemoryStream類案例運作效果圖

BufferedStream也在共享緩沖區中緩沖讀取和寫入。假設您幾乎始終執行一系列讀取或寫入操作,而很少在讀取和寫入之間切換。類BufferedStream的構造函數有2種重載,如表3-17所示:

表3-17 類BufferedStream的常用構造函數

<a>BufferedStream (Stream)</a>

使用預設的緩沖區大小 4096 位元組初始化 BufferedStream 類的新執行個體。

<a>BufferedStream (Stream, Int32)</a>

使用指定的緩沖區大小初始化 BufferedStream 類的新執行個體。

本文轉自 qianshao 51CTO部落格,原文連結:http://blog.51cto.com/qianshao/210979,如需轉載請自行聯系原作者