C#中的 MemoryStream和BinaryFormatter

來源:互聯網
上載者:User

標籤:des   style   http   使用   檔案   os   

編程訪問檔案是通過檔案流對象進行的,當應用程式需要訪問檔案時,必須先建立一個檔案流對象,此流對象和檔案是一一對應關係。
在.NET中,使用抽象基類System.IO.Stream代表流,它提供Read和Write兩個方法。由於資料流的有序性,因此流對象還有一個讀寫指標,為此,Stream類還有一個Seek方法用於移動讀寫指標。
FileStream對象的資料來自檔案,而MemoryStream對象的資料來自記憶體緩衝區。這兩個類都繼承自Stream類。

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

在建立MemoryStream對象時,可以指定緩衝區的大小,並且可以在需要的時候更改。
//位元組數組
byte[] buffer = new byte[600];
//填充位元組數組
private void CreateExampleData()
{
for(int i=0; i<600; i )
{
//byte類型的數最大不能超過255,用256模數實現
buffer[i] = (byte)(i%256);

}記憶體流的基本使用方法:
private void OnTestMemory()
{
//建立測試資料
CreateExampleData();

//建立記憶體流對象,初始分配50位元組的緩衝區
MemoryStream mem = new MemoryStream(50);

//向記憶體流中寫入位元組數組的所有資料
mem.Write(buffer,0,buffer.GetLength(0));

MessageBox.Show("寫入資料後的記憶體流長度:" mem.Length.ToString());
MessageBox.Show("分配給記憶體流的緩衝區大小:" mem.Capacity.ToString());

mem.SetLength(550);

MessageBox.Show("調用SetLength方法後的記憶體流長度:" mem.Length.ToString());

mem.Capacity = 620;//此值不能小於Length屬性
MessageBox.Show("調用Capacity方法後緩衝區大小:" mem.Capacity.ToString());

//將讀寫指標移到距流開頭10個位元組的位置
mem.Seek(10,SeekOrigin.Begin);
MessageBox.Show(mem.ReadByte().ToString());
mem.Close();
}記憶體流的Length屬性代表了其中存放的資料的真實長度,而Capacity屬性則代表了分配給記憶體流的記憶體空間大小。
可以使用位元組數組建立一個固定大小的MemoryStream,
MemoryStream mem = new MemoryStream(buffer);這時,無法再設定Capacity屬性的大小。
還可以建立唯讀記憶體流對象。
MemoryStream mem = new MemoryStream(buffer,false);
FlieStream用於存取檔案。
建立檔案並寫入內容:
//建立一個新檔案
FileStream fsForWrite = new FileStream("test.data",FileMode.Create);
try

//寫入一個位元組
fsForWrite.WriteByte(100);
CreateExampleData();
//將位元組數組寫入檔案
fsForWrite.Write(buffer,0,buffer.GetLength(0));
}
catch(Exception ex)

MessageBox.Show(ex.Message);
}
finally
{
//關閉檔案
fsForWrite.Close();
}開啟檔案並讀取內容:
private void ReadFromFile()
{
FileStream fsForRead = new FileStream("test.data",FileMode.Open);
try
{
//讀入一個位元組
MessageBox.Show("檔案的第一個位元組為:" fsForRead.ReadByte().ToString());
//讀寫指標移到距開頭10個位元組處
fsForRead.Seek(10,SeekOrigin.Begin);
byte[] bs = new byte[10];
//從檔案中讀取10個位元組放到數組bs中
fsForRead.Read(bs,0,10);
}
catch(Exception ex)

MessageBox.Show(ex.Message);
}
finally
{
fsForRead.Close(); }
}如果一個程式退出了,但它開啟的檔案沒有被關閉,將導致其他程式無法修改或刪除此檔案。
 

//-----------------------------------------------------------------------------------------------------------------------

BinaryFormatter序列化

序列化簡單點來理解就是把記憶體的東西寫到硬碟中,當然也可以寫到記憶體中(這個內容我會在後面寫一個例子).而還原序列化就是從硬碟中把資訊讀到記憶體中.就這麼簡單,呵呵,現在來看下面的例子吧!

在這篇文章中我將使用BinaryFormatter序列化類別Book作為例子,希望大家能從例子中深刻體會什麼是序列化.

定義類Book:

 

[Serializable]
 public class Book
 {
  string name;
  float    price;
  string author;

  public Book(string bookname, float bookprice, string bookauthor)
  {
   name = bookname;
   price = bookprice;
   author = bookauthor;
  }
 }

 

在類的上面增加了屬性:Serializable.(如果不加這個屬性,將拋出SerializationException異常).

通過這個屬性將Book標誌為可以序列化的.當然也有另一種方式使類Book可以序列化,那就是實行ISerializable介面了.在這裡大家要注意了:Serializable屬性是不能被繼承的咯!!!

如果你不想序列化某個變數,該怎麼處理呢?很簡單,在其前面加上屬性[NonSerialized] .比如我不想序列化

string author;

那我只需要

[NonSerialized]

string author;

好了,現在就告訴大家怎麼實現序列化:

我們使用namespace:

using System;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

 

首先建立Book執行個體,like this:  

 Book book = new Book("Day and Night", 30.0f, "Bruce");

接著當然要建立一個檔案了,這個檔案就是用來存放我們要序列化的資訊了.

FileStream fs = new FileStream(@"C:/book.dat", FileMode.Create);

序列化的實現也很簡單,like this:

    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(fs, book);

很簡單吧!現在我列出整個原代碼,包括還原序列化.

  

static void Main(string[] args)
  {
   Book book = new Book("Day and Night", 30.0f, "Bruce");

   using(FileStream fs = new FileStream(@"C:ook.dat", FileMode.Create))
   {
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(fs, book);
   }

   book = null;

   using(FileStream fs = new FileStream(@"C:ook.dat", FileMode.Open))
   {
    BinaryFormatter formatter = new BinaryFormatter();
    book = (Book)formatter.Deserialize(fs);//在這裡大家要注意咯,他的傳回值是object
   }
  }
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.