欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2013年05月18日 16:26:29   作者:  
本篇文章是對.Net中System.IO之Stream的使用進行了詳細的分析介紹,需要的朋友參考下
Stream在msdn的定義:提供字節(jié)序列的一般性視圖(provides a generic view of a sequence of bytes)。這個解釋太抽象了,不容易理解;從stream的字面意思“河,水流”更容易理解些,stream是一個抽象類,它定義了類似“水流”的事物的一些統(tǒng)一行為,包括這個“水流”是否可以抽水出來(讀取流內(nèi)容);是否可以往這個“水流”中注水(向流中寫入內(nèi)容);以及這個“水流”有多長;如何關(guān)閉“水流”,如何向“水流”中注水,如何從“水流”中抽水等“水流”共有的行為。
常用的Stream的子類有:
1) MemoryStream 存儲在內(nèi)存中的字節(jié)流
2) FileStream  存儲在文件系統(tǒng)的字節(jié)流
3) NetworkStream 通過網(wǎng)絡(luò)設(shè)備讀寫的字節(jié)流
4) BufferedStream 為其他流提供緩沖的流
Stream提供了讀寫流的方法是以字節(jié)的形式從流中讀取內(nèi)容。而我們經(jīng)常會用到從字節(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[]存儲從流中讀出的內(nèi)容
                    //第二個參數(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è)定的讀取數(shù)時表示到流的末尾了
                    if (readCn < readOnce) break;
                } while (true);
            }
            Console.Read();
        }
    }
}

2. 使用Stream.BeginRead方法讀取FileStream的流內(nèi)容
注意: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];

                //構(gòu)造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();
            }
        }
        //異步讀取回調(diào)處理方法
        public static void AsyncReadCallback(IAsyncResult asyncResult)
        {
            var asyncState = (AsyncState)asyncResult.AsyncState;
            int readCn = asyncState.FS.EndRead(asyncResult);
            //判斷是否讀到內(nèi)容
            if (readCn > 0)
            {
                byte[] buffer;
                if (readCn == bufferSize) buffer = asyncState.Buffer;
                else
                {
                    buffer = new byte[readCn];
                    Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn);
                }

                //輸出讀取內(nèi)容值
                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對象,然后向內(nèi)存流中寫入一個字節(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;
                }

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

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

                //注意在調(diào)用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方法異步寫;異步寫可以提高程序性能,這是因為磁盤或者網(wǎng)絡(luò)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>
        /// 異步回調(diào)需要的參數(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;
                //構(gòu)造回調(diào)函數(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>
        /// 異步寫的回調(diào)函數(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();
            }
        }
    }
}

相關(guān)文章

  • 基于C#委托的深入分析

    基于C#委托的深入分析

    本篇文章介紹了,基于C#委托的深入分析。需要的朋友參考下
    2013-04-04
  • WPF+SkiaSharp實現(xiàn)自繪投籃小游戲

    WPF+SkiaSharp實現(xiàn)自繪投籃小游戲

    這篇文章主要介紹了如何利用WPF+SkiaSharp實現(xiàn)自繪投籃小游戲。此案例主要是針對光線投影法碰撞檢測功能的示例,順便做成了一個小游戲,很簡單,但是,效果卻很不錯,感興趣的可以動手嘗試一下
    2022-08-08
  • C# 對XML基本操作代碼總結(jié)

    C# 對XML基本操作代碼總結(jié)

    C# 對XML基本操作包括讀取節(jié)點的數(shù)據(jù),添加節(jié)點。讀取節(jié)點屬性,修改節(jié)點屬性等
    2011-10-10
  • C#代替go采用的CSP并發(fā)模型實現(xiàn)

    C#代替go采用的CSP并發(fā)模型實現(xiàn)

    這篇文章主要為大家介紹了C#代替go采用的CSP并發(fā)模型的輕松實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • C# 獲取枚舉值的簡單實例

    C# 獲取枚舉值的簡單實例

    這篇文章介紹了C# 獲取枚舉值的簡單實例,有需要的朋友可以參考一下
    2013-09-09
  • C#中判斷某類型是否可以進行隱式類型轉(zhuǎn)換

    C#中判斷某類型是否可以進行隱式類型轉(zhuǎn)換

    在我們采用反射動態(tài)調(diào)用一些方法時,常常涉及到類型的轉(zhuǎn)換,直接判斷類型是否相符有時不能判斷調(diào)用方法是否合適
    2013-04-04
  • C#實現(xiàn)打開指定目錄和指定文件的示例代碼

    C#實現(xiàn)打開指定目錄和指定文件的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)打開指定目錄、打開指定目錄且選中指定文件、打開指定文件,感興趣的小伙伴可以嘗試一下
    2022-06-06
  • C#二進制序列化實例分析

    C#二進制序列化實例分析

    這篇文章主要介紹了C#二進制序列化,實例分析了C#二進制序列化的方法,代碼中有較為詳盡的注釋說明,便于理解,需要的朋友可以參考下
    2015-05-05
  • 詳解c# 并行計算

    詳解c# 并行計算

    本文主要介紹了并行計算的簡單使用,并行循環(huán)的中斷和跳出、并行循環(huán)中為數(shù)組/集合添加項、返回集合運算結(jié)果/含有局部變量的并行循環(huán)、、PLinq(Linq的并行計算)等相關(guān)內(nèi)容。
    2020-12-12
  • Unity多語言轉(zhuǎn)換工具的實現(xiàn)

    Unity多語言轉(zhuǎn)換工具的實現(xiàn)

    這篇文章主要為大家詳細介紹了Unity多語言轉(zhuǎn)換工具的實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論