2013-08-22 25 views
0

我想問一下使用二進制格式化程序的序列化/反序列化對象。以及我試圖反序列化FileStream中包含許多對象已逐個序列化的對象。一個對象的大小太大,無法保存在進程內存中,這就是爲什麼我不把所有對象都打包在一個對象中的原因,例如:List,因爲它們在進程內存中過大所以我多次按需要序列化。以這種方式,它不會佔用很多進程內存,因爲我只交替處理一個對象而不是所有的對象。看看素描,我的意思是二進制格式化程序,設置反序列化特定對象的位置

<FileStream> 
----Object 1-----Size = 100 Mb------index = 0 
----Object 2-----Size = 100 Mb------index = 1 
----Object 3-----Size = 100 Mb------index = 2 
----Object 4-----Size = 100 Mb------index = 3 
----Object 5-----Size = 100 Mb------index = 4 
----Object 6-----Size = 100 Mb------index = 5 
</FileStream> 

序列化對象也成功了現在我得到了一個問題來反序列化一個對象。 這裏是問題: 在列表我們可以帶索引的項目。所以如果我們想借此第五索引,我們可以稱之爲比如:

List<object> list = new List<object>(); 
    list(0) = "object1"; 
    list(1) = "object2"; 
    list(2) = "object3"; 
    list(3) = "object4"; 
    list(4) = "object5"; 
    list(5) = "object6"; 
    object fifthIndex = list[5]; // here we can get item based index 

那麼現在的問題是我怎麼可以得到第五索引對象就像在六個反序列化對象列表方法在FILESTREAM與二進制格式化程序。我知道在FileStream中有一個名爲「FileStream.Position」的屬性,但它不喜歡索引,它看起來像一個隨機數,當我反序列化/序列化一個對象。也許它會增加隨機數。

其實我已經成功的,但我敢肯定,這是不是最好的方式來看看我的代碼,我曾經嘗試過:

object GetObjectStream(FileStream fs, int index) 
{ 
    if (fs != null) 
    { 
     BinaryFormatter binaryformatter = new BinaryFormatter(); 
     bool isFinished = false; int count = 0; 
     while (isFinished == false) 
     { 
      try 
      { 
       object objectdeserialized = binaryformatter.Deserialize(fs); 
       if (count == index) return objectdeserialized; 
       count++; 
      } 
      catch 
      { 
       isFinished = true; 
       return null; 
      } 
     } 
    } 
    return null; 
} 

這些代碼將「的foreach」每個對象已經序列化,然後反序列化每個對象。我敢打賭,我的代碼並不是最好的方式,因爲反序列化包含100 MB的對象可能需要很長時間,我甚至不知道除了索引以外的對象是否會被反序列化?我想要的方法就像「序列化飛躍」。

如果我們能解決這個問題,你的回答對我非常有幫助和有用。前

謝謝..

+0

顯示它是序列化列表的代碼。 –

+0

,我的意思是序列化@DarinDimitrov列表對象是: binaryformatter.Serialize(新列表()); 遠的不說有新的列表(),然後我序列化了很多項目。 – Ricks

+0

但是如果列表中有很多項目,它們如何適應內存?我認爲這首先是你的問題 - 因爲名單太龐大,內存不足。 –

回答

1

每個對象很可能會採取不同的空間序列化 - 數據包不同,特別是對於像字符串和數組。基本上,要有效地做到這一點(即沒有讀全,每次每個對象),你會想要麼:

  • 前綴需要,通過將其序列化到MemoryStream,存儲.Length(任何方式,方便數據量的每個對象你;一個4字節的little-endian塊就足夠了),然後將你寫到MemoryStream的數據複製到輸出中;然後就可以通過正 - 時間─跳到第n個項(讀取4個字節作爲一個int,跳過許多字節)在一個單獨的索引
  • ,存儲所述基本流的.Position序列化的每個對象之前;然後讀取第n個對象,可以使用該索引來查找你需要的位置,並滾動到那裏

其實,你是相當幸運的位置:BinaryFormatter實際上不記錄爲安全追加,但由於它發生了確實有點工作了好吧,你這樣做 - 但這不是所有的序列化格式。

就個人而言,雖然,我懷疑是否有很簡單,就是可以在這裏使用了不同的設計。

+0

好吧,我明白了。與你的第二個解決方案,現在的問題是,我們序列化我有的所有對象後,我們得到所有**索引/位置長度**。那麼現在我怎樣才能把**「Index/Position」**放到File的頭部,而我們已經完成了6次序列化。我如何設置位置爲0序列化標題,而序列化流越來越錯誤,因爲位置不整潔。 – Ricks

+0

@Rizky你不能神奇地將事情事後轉移到文件的「標題」中;首先,這需要你移動所有其餘的數據***,第二:這將改變偏移量 - 儘管如此,你可能只是通過標題大小來抵消所有事情而作弊。但是,在那一點上,你已經使事情從根本上不可追加,因此爲什麼我使用了「分開」這個詞,這將允許你繼續使用它。如果你想要一個單獨的文件,**和**你希望它是可追加的,你需要使用第一種方法或不同的序列化程序。/ –

+0

我遵循了你的建議,它已經解決了。我讀回你的建議,這是使用** MemoryStream **然後複製數據的內容和索引位置也,這是工作正常!我非常感謝你,但這仍然不能解決我的其他問題。現在回到我的問題:我需要序列化每個對象高達100 MB的數據量。有了這個大小,即使我需要序列化20個對象,我需要在內存流中一次處理它,在進程內存中的大小將達到2 GB!這會導致**程序崩潰,**當然這個問題相當困難。 – Ricks

相關問題