BufferedStream類 - 緩沖流


  BufferedStream常用於對其他流的一個封裝,它必須和其他流結合一起使用。MemoryStream將所有的內容都放入內存中,而BufferedStream不是。BufferedStream在基礎流寫入內存中能夠提高讀取與寫入速度。但是緩沖區設置的大小對性能也有影響,默認值是4096字節,並能夠根據需求自動增長。並且很多屬性都與基礎流一致。緩沖數據能夠減少對操作系統的調用次數,緩沖數據主要存儲在緩沖區中,緩沖區是內存中的字節塊。BufferedStream類提供從基礎數據源或存儲庫讀取字節以及將字節寫入基礎數據源或存儲庫的實現,在不需要緩沖區時可以防止緩沖區降級輸入和輸出速度。

  緩沖類型下,會在后台自動下載定長的內容,讀的時候是從緩沖區中拿東西。這種模式最大的特點是半阻塞式,大部分情況下能大幅度提高處理速度。

  在程序邏輯速度大大慢於IO速度時,此方法效率明顯。最好是在大文件的情況下,分塊讀,分塊寫。

一、構造函數

BufferedStream(Stream)
  其實BufferedStream的構造主要功能還是設置緩沖區大小,如果沒有指定則默認是用4096字節的進行初始化
BufferedStream(Stream, Int32)
  第二個參數是手動指定緩沖區大小
  第一次使用此構造函數初始化 BufferedStream 對象時分配共享讀/寫緩沖區。 如果所有的讀和寫都大於或等於緩沖區大小,則不使用共享緩沖區。

二、屬性

CanRead     獲取一個值,該值指示當前流是否支持讀取。
CanSeek     獲取一個值,該值指示當前流是否支持查找。
CanTimeout    獲取一個值,該值確定當前流是否可以超時。
CanWrite      獲取一個值,該值指示當前流是否支持寫入。
Length       獲取流長度,長度以字節為單位。
Position      獲取當前流內的位置。get 訪問器調用 Seek 獲取基礎流中的當前位置,然后根據緩沖區中的當前位置調整此值。set 訪問器將以前寫入緩沖區的所有數據都           復制到基礎流中,然后調用 Seek。
ReadTimeout  獲取或設置一個值(以毫秒為單位),該值確定流在超時前嘗試讀取多長時間。
WriteTimeout   獲取或設置一個值(以毫秒為單位),該值確定流在超時前嘗試寫入多長時間。

三、方法

BeginRead     開始異步讀操作。 (繼承自 Stream。)
BeginWrite      開始異步寫操作。 (繼承自 Stream。)
Close        已重載。
CreateObjRef    創建一個對象,該對象包含生成用於與遠程對象進行通信的代理所需的全部相關信息。 (繼承自 MarshalByRefObject。)
CreateWaitHandle 已過時。分配 WaitHandle 對象。 (繼承自 Stream。)
Dispose      已重載。
EndRead       等待掛起的異步讀取完成。 (繼承自 Stream。)
EndWrite      結束異步寫操作。 (繼承自 Stream。)
Flush        清除該流的所有緩沖區,使得所有緩沖的數據都被寫入到基礎設備。 (重寫 Stream..::.Flush()()()。)
GetLifetimeService     檢索控制此實例的生存期策略的當前生存期服務對象。 (繼承自 MarshalByRefObject。)
InitializeLifetimeService    獲取控制此實例的生存期策略的生存期服務對象。 (繼承自 MarshalByRefObject。)
MemberwiseClone      已重載。
Read             將字節從當前緩沖流復制到數組。 (重寫 Stream..::.Read(array<Byte>[]()[], Int32, Int32)。)
ReadByte          從基礎流中讀取一個字節,並返回轉換為 int 的該字節;或者如果從流的末尾讀取則返回 -1。 (重寫 Stream..::.ReadByte()()()。)
Seek             設置當前緩沖流中的位置。 (重寫 Stream..::.Seek(Int64, SeekOrigin)。)
SetLength         設置緩沖流的長度。 (重寫 Stream..::.SetLength(Int64)。)
Write            將字節復制到緩沖流,並將緩沖流內的當前位置前進寫入的字節數。 (重寫 Stream..::.Write(array<Byte>[]()[], Int32, Int32)。)
WriteByte         將一個字節寫入緩沖流的當前位置。 (重寫 Stream..::.WriteByte(Byte)。)

最后寫了個示例:

        static void Main(string[] args)
        {
            FileStream fs = new FileStream(@"D:\text.txt",FileMode.Open,FileAccess.ReadWrite);
            BufferedStream bs = new BufferedStream(fs);
            Console.WriteLine(bs.CanRead);  //此流於基礎流的設置有關,當fs設FileAccess.Read時就為true,Write時就為false
            Console.WriteLine(fs.CanSeek + " " + bs.CanSeek);  //True True  支持查找
            Console.WriteLine(fs.CanTimeout + " " + bs.CanTimeout);   //False False 既然不支持超時,那就更加不存在超過多久的問題了,因此最后兩個屬性都會異常。
            Console.WriteLine(bs.CanWrite); //這個也是和基礎流的可讀屬性一致
            Console.WriteLine(fs.Length + " " + bs.Length);    //輸出 7649 7649
            Console.WriteLine(fs.Length + " " + bs.Position); //輸出7649  0   文件流Open打開就在最后了,但是BufferedStream是在開始。

            //也是這樣讀寫,與FileStream無異,不過在內存讀取應該會快點。
            byte[] bytes = new byte[bs.Length];
            bs.Read(bytes, 0, (int)bs.Length);
            Console.WriteLine(Encoding.UTF8.GetString(bytes));

            //也是與FileStream的寫入方式一樣,連Flush都一樣
            byte[] byte1 = Encoding.UTF8.GetBytes("你在他鄉還好嗎?");
            bs.Write(byte1,0,byte1.Length);
            bs.Flush(); //還是這樣寫

            Console.ReadKey();
        }

 以下給出一個使用緩沖流復制文件的例子:

    class Program
    {
        static void Main(string[] args)
        {
            string Path1 = @"D:\123.txt";
            string Path2 = @"D:\456.txt";
            Buf(Path1,Path2);
            Console.WriteLine("文件復制完成!");

            Console.ReadKey();
        }

        private static void Buf(string oPath, string copyPath)
        {
            Stream s1, s2;
            BufferedStream bs1, bs2;
            byte[] b = new byte[1024];
            int i;
            //分別以讀、寫方式打開兩個文件
            s1 = File.OpenRead(oPath);
            s2 = File.OpenWrite(copyPath);
            //使用緩沖流
            bs1 = new BufferedStream(s1);
            bs2 = new BufferedStream(s2);
            i = bs1.Read(b,0,1024);
            //從文件1中讀取,寫入到文件2中
            while (i > 0)
            {
                bs2.Write(b,0,i);
                i = bs1.Read(b,0,1024);
            }
            bs2.Flush();
            s1.Close();
            bs2.Close();
        }
    }

 


免責聲明!

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



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