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

C#使用文件流FileStream和內(nèi)存流MemoryStream操作底層字節(jié)數(shù)組byte[]

 更新時(shí)間:2022年05月11日 09:37:51   作者:springsnow  
這篇文章介紹了C#使用文件流FileStream和內(nèi)存流MemoryStream操作底層字節(jié)數(shù)組byte[]的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、Stream類概述

在.NET Framework中,文件和流是有區(qū)別的。

文件是存儲在磁盤上的數(shù)據(jù)集,它具有名稱和相應(yīng)的路徑。當(dāng)打開一個(gè)文件并對其進(jìn)行讀/寫時(shí),該文件就稱為流(stream)。

但是,流不僅僅是指打開的磁盤文件,還可以是網(wǎng)絡(luò)數(shù)據(jù)。.Net Framework允許在內(nèi)存中創(chuàng)建流。此外,在控制臺應(yīng)用程序中,鍵盤輸入和文本顯示都是流。 

1. Stream類

Stream類是所有流的抽象基類。

Stream類的主要屬性有CanRead、CanWrite(是否支持讀取寫入)、CanSeek(是否支持查找)、CanTimeout(是否可以超時(shí))、Length(流的長度)、Position(獲取或設(shè)置當(dāng)前流中的位置)、ReadTimeout/WriteTimeout(獲取或設(shè)置讀、寫操作的超時(shí)時(shí)間)

Stream類的主要方法有BeginRead/EndRead(開始結(jié)束異步讀操作),BeginWrite/EndWrite(開始結(jié)束異步寫操作)、Read(讀取字節(jié)序列)、ReadByte(讀取一個(gè)字節(jié))、Seek(設(shè)置查找位置)、Write(寫入字節(jié)序列)、WriteByte(寫入一個(gè)字節(jié))、 Flush(清除流的所有緩沖區(qū)并把緩沖數(shù)據(jù)寫入基礎(chǔ)設(shè)備)、Close(關(guān)閉當(dāng)前流)。

2. FileStream、MemoryStream、BufferedStream和NetworkStream

  • 文件流類FileStream:以流的形式讀、寫、打開、關(guān)閉文件。另外,它還可以用來操作諸如:管道、標(biāo)準(zhǔn)輸入/輸出等其他與文件相關(guān)的操作系統(tǒng)句柄。
  • 內(nèi)存流MemoryStream類:用來在內(nèi)存中創(chuàng)建流,以暫時(shí)保持?jǐn)?shù)據(jù),因此有了它就無須在硬盤上創(chuàng)建臨時(shí)文件。它將數(shù)據(jù)封裝為無符號的字節(jié)序列,可以直接進(jìn)行讀、寫、查找操作。
  • 緩沖流BufferedStream類:表示把流先添加到緩沖區(qū),再進(jìn)行數(shù)據(jù)的讀/寫操作。緩沖區(qū)是存儲區(qū)中用來緩存數(shù)據(jù)的字節(jié)塊。使用緩沖區(qū)可以減少訪問數(shù)據(jù)時(shí)對操作系統(tǒng)的調(diào)用次數(shù),增強(qiáng)系統(tǒng)的讀/寫功能。
  • 網(wǎng)絡(luò)流NetworkStream類:為網(wǎng)絡(luò)訪問提供數(shù)據(jù)的基礎(chǔ)流。

注意,F(xiàn)ileStream類也有緩沖功能,在創(chuàng)建FileStream類的實(shí)例時(shí),只需要指定緩沖區(qū)的大小即可。

二、文件流類 FileStream

文件流類FileStream公開了以文件為主的Stream,既支持同步讀/寫操作,也支持異步讀/寫操作。

FileStream類的特點(diǎn)是操作字節(jié)和字節(jié)數(shù)組。這種方式不適合操作用字符數(shù)據(jù)構(gòu)成的文本文件,適合處理非文本文件。

FileStream類提供了對文件的低級而復(fù)雜的操作,因此能夠?qū)崿F(xiàn)更多高級的功能。

1、讀文件

Read,ReadByte()

//創(chuàng)建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
byte[] bData = new byte[fstream.Length];
//設(shè)置流當(dāng)前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);

//將文件的內(nèi)容存到字節(jié)數(shù)組中(緩存)
fstream.Read(bData, 0, bData.Length);
string result = Encoding.UTF8.GetString(bData);
Console.WriteLine(result);
if (fstream != null)
{
    //清除此流的緩沖區(qū),使得所有緩沖的數(shù)據(jù)都寫入到文件中
    fstream.Flush();
    fstream.Close();
}

將字節(jié)數(shù)組轉(zhuǎn)成字符串顯示以外,字節(jié)數(shù)組還可以

//1、顯示成圖片
MemoryStream mstream = new MemoryStream(bData);
Image img = Image.FromStream(mstream);

 //2、作為值存儲到數(shù)據(jù)庫
SqlCommand comm = new SqlCommand();
comm.Parameters.Add("images", SqlDbType.Image).Value = bData;

 //3、寫入文件
File.WriteAllBytes("c:\aa.txt", bData);
FileStream fstream = new FileStream("c:\aa.txt");
fstream.Write(bData, 0, bData.Length);

2、分塊讀文件

int bufferSize = 5;
//創(chuàng)建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, false);//false表示同步讀
byte[] bData = new byte[bufferSize];
//設(shè)置流當(dāng)前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);
int bytesRead;
do
{
    //將文件的內(nèi)容存到字節(jié)數(shù)組中(緩存)
    bytesRead = fstream.Read(bData, 0, bData.Length);
    string result = Encoding.UTF8.GetString(bData, 0, bytesRead);
    Console.WriteLine(result);
} while (bytesRead > 0);

if (fstream != null)
{
    //清除此流的緩沖區(qū),使得所有緩沖的數(shù)據(jù)都寫入到文件中
    fstream.Flush();
    fstream.Close();
}

3、異步讀文件

ManualResetEvent mEvent = new ManualResetEvent(false);
int bufferSize = 5;
byte[] bData = new byte[bufferSize];
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, true);//false表示異步讀

AsyncCallback callback = null;
callback = (IAsyncResult ar) => 
  {
      int bytesRead = fstream.EndRead(ar);
      Console.WriteLine(Encoding.UTF8.GetString(bData, 0, bytesRead));
      if (bytesRead > 0)
      {
          fstream.BeginRead(bData, 0, bufferSize, callback, null);//繼續(xù)讀
      }
      else
      {
          fstream.Close();
          mEvent.Set();//讀取完畢,發(fā)送信號
      }
  };

IAsyncResult async = fstream.BeginRead(bData, 0, bufferSize, callback, null);
mEvent.WaitOne(5000, false);
Console.WriteLine("讀取完成");

備注:IAsyncResult 接口的成員

AsyncState 獲取一個(gè)用戶定義的對象,該對象限定或包含有關(guān)異步操作的信息。

AsyncWaitHandle 獲取用于等待異步操作完成的 WaitHandle。

CompletedSynchronously 獲取一個(gè)值,該值指示異步操作是否同步完成。

IsCompleted 獲取一個(gè)值,該值指示異步操作是否已完成。

4、寫文件

Write,WriteByte(Byte)

//創(chuàng)建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
byte[] bData = Encoding.UTF8.GetBytes("test filestream");
//設(shè)置流當(dāng)前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);

//將字節(jié)數(shù)組中的內(nèi)容寫入文件
fstream.Write(bData, 0, bData.Length);
if (fstream != null)
{
    //清除此流的緩沖區(qū),使得所有緩沖的數(shù)據(jù)都寫入到文件中
    fstream.Flush();
    fstream.Close();
}

三、內(nèi)存流MemoryStream類

內(nèi)存流相對字節(jié)數(shù)組而言,具有流特有的特性,并且容量可自動(dòng)增長。

在數(shù)據(jù)加密以及對長度不定的數(shù)據(jù)進(jìn)行緩存等場合,使用內(nèi)存流比較方便。

下面的代碼示例演示如何讀取和寫入將內(nèi)存用作后備存儲的數(shù)據(jù)。

int count;
UnicodeEncoding uniEncoding = new UnicodeEncoding();

//創(chuàng)建要寫入流的數(shù)據(jù) 
byte[] firstString = uniEncoding.GetBytes("Invalid file path characters are: ");
byte[] secondString = uniEncoding.GetBytes(Path.GetInvalidPathChars());

using (MemoryStream memStream = new MemoryStream(100))
{
    // 將第一個(gè)字符串寫入流.
    memStream.Write(firstString, 0, firstString.Length);

    // 將第二個(gè)字符串按字節(jié)寫入流.
    count = 0;
    while (count < secondString.Length)
    {
        memStream.WriteByte(secondString[count++]);
    }

    // 將流屬性寫入控制臺.
    Console.WriteLine("Capacity = {0}, Length = {1}, Position = {2}\n", memStream.Capacity.ToString(), memStream.Length.ToString(), memStream.Position.ToString());

    // 將位置設(shè)置為流的開始.
    memStream.Seek(0, SeekOrigin.Begin);

    // 從流中讀取前20個(gè)字節(jié).
    byte[] byteArray = new byte[memStream.Length];
    count = memStream.Read(byteArray, 0, 20);

    // 一個(gè)字節(jié)一個(gè)字節(jié)地讀取剩下的字節(jié).
    while (count < memStream.Length)
    {
        byteArray[count++] = Convert.ToByte(memStream.ReadByte());
    }

    // 將字節(jié)數(shù)組解碼為char數(shù)組并將其寫入控制臺.
    char[] charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)];
    uniEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);
    Console.WriteLine(charArray);
}

ToArray()與GetBuffer()的區(qū)別:

//將流中的數(shù)據(jù)復(fù)制到一個(gè)byte[]中,速度比GetBuffer()稍慢,但不會將無用的空數(shù)據(jù)放入buffer中。 
byte[] byteArray = memStream.ToArray();

//把流中的Buffer的引用傳遞出來,速度較快,Buffer的大小有流的Capacity決定的,但會傳無用的空數(shù)據(jù)。
byte[] byteArray = memStream.GetBuffer();

到此這篇關(guān)于C#使用文件流FileStream和內(nèi)存流MemoryStream操作底層字節(jié)數(shù)組byte[]的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論