a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

.Net筆記:System.IO之Stream的使用詳解

2020-01-24 03:18:23
字體:
來源:轉載
供稿:網友
Stream在msdn的定義:提供字節(jié)序列的一般性視圖(provides a generic view of a sequence of bytes)。這個解釋太抽象了,不容易理解;從stream的字面意思“河,水流”更容易理解些,stream是一個抽象類,它定義了類似“水流”的事物的一些統(tǒng)一行為,包括這個“水流”是否可以抽水出來(讀取流內容);是否可以往這個“水流”中注水(向流中寫入內容);以及這個“水流”有多長;如何關閉“水流”,如何向“水流”中注水,如何從“水流”中抽水等“水流”共有的行為。
常用的Stream的子類有:
1) MemoryStream 存儲在內存中的字節(jié)流
2) FileStream  存儲在文件系統(tǒng)的字節(jié)流
3) NetworkStream 通過網絡設備讀寫的字節(jié)流
4) BufferedStream 為其他流提供緩沖的流
Stream提供了讀寫流的方法是以字節(jié)的形式從流中讀取內容。而我們經常會用到從字節(jié)流中讀取文本或者寫入文本,微軟提供了StreamReader和StreamWriter類幫我們實現(xiàn)在流上讀寫字符串的功能。
下面看下如何操作Stream,即如何從流中讀取字節(jié)序列,如何向流中寫字節(jié)
1. 使用Stream.Read方法從流中讀取字節(jié),如下示例注釋:
復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStream
{
    class Program
    {
        //示例如何從流中讀取字節(jié)流
        static void Main(string[] args)
        {
            var bytes = new byte[] {(byte)1,(byte)2,(byte)3,(byte)4,(byte)5,(byte)6,(byte)7,(byte)8};
            using (var memStream = new MemoryStream(bytes))
            {
                int offset = 0;
                int readOnce = 4;
                do
                {
                    byte[] byteTemp = new byte[readOnce];
                    // 使用Read方法從流中讀取字節(jié)
                    //第一個參數(shù)byte[]存儲從流中讀出的內容
                    //第二個參數(shù)為存儲到byte[]數(shù)組的開始索引,
                    //第三個int參數(shù)為一次最多讀取的字節(jié)數(shù)
                    //返回值是此次讀取到的字節(jié)數(shù),此值小于等于第三個參數(shù)
                    int readCn = memStream.Read(byteTemp, 0, readOnce);
                    for (int i = 0; i < readCn; i++)
                    {
                        Console.WriteLine(byteTemp[i].ToString());
                    }

                    offset += readCn;

                    //當實際讀取到的字節(jié)數(shù)小于設定的讀取數(shù)時表示到流的末尾了
                    if (readCn < readOnce) break;
                } while (true);
            }
            Console.Read();
        }
    }
}

2. 使用Stream.BeginRead方法讀取FileStream的流內容
注意:BeginRead在一些流中的實現(xiàn)和Read完全相同,比如MemoryStream;而在FileStream和NetwordStream中BeginRead就是實實在在的異步操作了。
如下示例代碼和注釋:
復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseBeginRead
{
    class Program
    {
        //定義異步讀取狀態(tài)類
        class AsyncState
        {
            public FileStream FS { get; set; }

            public byte[] Buffer { get; set; }

            public ManualResetEvent EvtHandle { get; set; }
        }
        static  int bufferSize = 512;
        static void Main(string[] args)
        {
            string filePath = "d://test.txt";
            //以只讀方式打開文件流
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var buffer = new byte[bufferSize];

                //構造BeginRead需要傳遞的狀態(tài)
                var asyncState = new AsyncState { FS = fileStream, Buffer = buffer ,EvtHandle = new ManualResetEvent(false)};

                //異步讀取
                IAsyncResult asyncResult = fileStream.BeginRead(buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);

                //阻塞當前線程直到讀取完畢發(fā)出信號
                asyncState.EvtHandle.WaitOne();
                Console.WriteLine();
                Console.WriteLine("read complete");
                Console.Read();
            }
        }
        //異步讀取回調處理方法
        public static void AsyncReadCallback(IAsyncResult asyncResult)
        {
            var asyncState = (AsyncState)asyncResult.AsyncState;
            int readCn = asyncState.FS.EndRead(asyncResult);
            //判斷是否讀到內容
            if (readCn > 0)
            {
                byte[] buffer;
                if (readCn == bufferSize) buffer = asyncState.Buffer;
                else
                {
                    buffer = new byte[readCn];
                    Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn);
                }

                //輸出讀取內容值
                string readContent = Encoding.UTF8.GetString(buffer);
                Console.Write(readContent);
            }

            if (readCn < bufferSize)
            {
                asyncState.EvtHandle.Set();
            }
            else {
                Array.Clear(asyncState.Buffer, 0, bufferSize);
                //再次執(zhí)行異步讀取操作
                asyncState.FS.BeginRead(asyncState.Buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);
            }
        }
    }
}

3. 使用Stream.Write方法向流中寫字節(jié)數(shù)組
在使用Write方法時,需要先使用Stream的CanWrite方法判斷流是否可寫,如下示例定義了一個MemoryStream對象,然后向內存流中寫入一個字節(jié)數(shù)組
復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStreamWrite
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ms = new MemoryStream())
            {
                int count = 20;
                var buffer = new byte[count];
                for (int i = 0; i < count; i++)
                {
                    buffer[i] = (byte)i;
                }

                //將流當前位置設置到流的起點
                ms.Seek(0, SeekOrigin.Begin);

                Console.WriteLine("ms position is " + ms.Position);

                //注意在調用Stream的Write方法之前要用CanWrite判斷Stream是否可寫
                if (ms.CanWrite)
                {
                    ms.Write(buffer, 0, count);
                }

                //正確寫入的話,流的位置會移動到寫入開始位置加上寫入的字節(jié)數(shù)
                Console.WriteLine("ms position is " + ms.Position);
            }

            Console.Read();
        }
    }
}

4. 使用Stream.BeginWrite方法異步寫;異步寫可以提高程序性能,這是因為磁盤或者網絡IO的速度遠小于cpu的速度,異步寫可以減少cpu的等待時間。
如下使用FileStream異步寫文件的操作示例
復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseStreamBeginWrite
{
    class Program
    {
        /// <summary>
        /// 異步回調需要的參數(shù)封裝類
        /// </summary>
        class AsyncState {
            public int WriteCountOnce { get; set; }
            public int Offset { get; set; }
            public byte[] Buffer { get; set; }
            public ManualResetEvent WaitHandle { get; set; }
            public FileStream FS { get; set; }
        }
        static void Main(string[] args)
        {
            //準備一個1K的字節(jié)數(shù)組
            byte[] toWriteBytes = new byte[1 << 10];
            for (int i = 0; i < toWriteBytes.Length; i++)
            {
                toWriteBytes[i] = (byte)(i % byte.MaxValue);
            }
            string filePath = "d://test.txt";
            //FileStream實例
            using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
            {
                int offset = 0;
                //每次寫入32字節(jié)
                int writeCountOnce = 1 << 5;
                //構造回調函數(shù)需要的狀態(tài)
                AsyncState state = new AsyncState{
                    WriteCountOnce = writeCountOnce,
                    Offset = offset,
                    Buffer = toWriteBytes,
                    WaitHandle = new ManualResetEvent(false),
                    FS = fileStream
                };

                //做異步寫操作
                fileStream.BeginWrite(toWriteBytes, offset, writeCountOnce, WriteCallback, state);

                //等待寫完畢或者出錯發(fā)出的繼續(xù)信號
                state.WaitHandle.WaitOne();
            }
            Console.WriteLine("Done");
            Console.Read();
        }
        /// <summary>
        /// 異步寫的回調函數(shù)
        /// </summary>
        /// <param name="asyncResult">寫狀態(tài)</param>
        static void WriteCallback(IAsyncResult asyncResult)
        {
            AsyncState state = (AsyncState)asyncResult.AsyncState;

            try
            {
                state.FS.EndWrite(asyncResult);
            }
            catch (Exception ex)
            {
                Console.WriteLine("EndWrite Error:" + ex.Message);
                state.WaitHandle.Set();
                return;
            }

            Console.WriteLine("write to " + state.FS.Position);
            //判斷是否寫完,未寫完繼續(xù)異步寫
            if (state.Offset + state.WriteCountOnce < state.Buffer.Length)
            {
                state.Offset += state.WriteCountOnce;
                Console.WriteLine("call BeginWrite again");
                state.FS.BeginWrite(state.Buffer, state.Offset, state.WriteCountOnce, WriteCallback, state);
            }
            else {
                //寫完發(fā)出完成信號
                state.WaitHandle.Set();
            }
        }
    }
}

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: www久久久久 | 久久国产在线视频 | 国产精品视频一区在线观看 | 国产精品色 | 欧美午夜一区二区三区免费大片 | 国产日韩免费 | 在线 丝袜 欧美 日韩 制服 | 99re6在线视频精品免费 | 久久久久久久成人 | 国产男女爽爽爽免费视频 | 国产精品一区在线观看你懂的 | 毛片aaaaa | 亚洲视频中文字幕 | 久草成人网 | 久久精品小视频 | 中文字幕日韩一区二区不卡 | 玖玖成人 | 91精品国产乱码久久久久久久久 | 国产小视频在线观看 | 91久久久久久久久久久久久久久久 | 在线不卡av | 日韩成人午夜 | 国产精品91网站 | 久久亚洲欧美日韩精品专区 | 91视频免费观看入口 | 久久一区二区av | 欧美一区二区三区视频 | 曰韩精品一区二区 | 99精品99| 日本五月婷婷 | 久久国产一区二区 | 国产一区二区在线播放 | 日韩精品在线免费观看 | 一区二区三区精品 | 国产丝袜一区二区三区免费视频 | 日韩欧美视频一区二区三区 | 亚洲高清视频一区二区三区 | 亚洲精品免费在线观看 | 欧美日韩精品 | 亚洲成人伦理 | 青草精品|