2014-05-09 62 views
2

我正在使用protobuf將大對象序列化爲二進制文件進行反序列化並在以後再次使用。但是,當我反序列化一些較大的文件時,我遇到了問題。該文件是大約2.3〜GB的大小,當我嘗試反序列化他們,我得到一些例外拋出(按以下順序):反序列化大文件時的Protobuf異常

我已經查看了第二個異常中引用的問題,但似乎沒有涵蓋我遇到的問題。

我使用的是微軟的HPC包來生成這些文件(他們需要一段時間),所以序列化看起來是這樣的:

using (var consoleStream = Console.OpenStandardOutput()) 
    { 
      Serializer.Serialize(consoleStream, dto); 
    } 

而且我讀文件如下:

private static T Deserialize<T>(string file) 
    { 
     using (var fs = File.OpenRead(file)) 
     { 
      return Serializer.Deserialize<T>(fs); 
     } 
    } 

這些文件是兩種不同的類型。一個大小約1GB,另一個約2.3GB。較小的文件都可以工作,較大的文件不會。任何想法可能在這裏出錯?我意識到我沒有給出很多細節,可以根據要求提供更多細節。

+2

*反序列化*和* 2.3 GB *已經聽起來不對。無視錯誤,使用任何種類的序列化來處理這麼大量的數據是不好的。你能詳細說明你正在試圖通過使用序列化解決什麼問題嗎? – Sinatr

+0

@Sinatr是的,我已經意識到可能這不是最好的路線,但我現在有文件試圖挽救他們。我需要能夠生成這些文件並將它們保存到磁盤供以後使用。 – geekchic

+0

有什麼用?你能準確地告訴這些文件是什麼嗎?也許你決定使用序列化或其他方式來傳輸(導出/導入?)數據,其中序列化(對於這樣的數據量)是一個壞主意。考慮使用自定義文件格式,那麼大量數據(HPC包?這是什麼?)只是被複制到1,而小部分(包含配置,路徑,參數等)是以經典方式序列化,然後與大量數據。 – Sinatr

回答

1

在這裏,我需要參考最近的討論上protobuf list

的Protobuf使用INT來表示大小,因此它可以支持可能的最大尺寸是< 2G。我們沒有計劃在代碼中將int更改爲size_t。用戶應避免使用過大的消息。

猜測是protobuf網內失敗的原因基本相同。我大概可以改變protobuf-net來支持更大的文件,但我必須建議,這是而不是推薦,因爲它看起來沒有其他實現可以很好地處理如此巨大的數據。

解決方法是可能只是在讀/寫器層改變了很多intlong的情況。但是:數據的佈局是什麼?如果有一個外部對象基本上是對象的列表,則可能會使用增量式閱讀器(基本上是直接欺騙repeated支持)來做到這一點。

+0

有一個外部對象上有幾個(相當大)的字典。讀者如何喜歡這項工作? – geekchic

+0

基本上,使用外部讀取器來讀取物品的長度,並使用內部讀取器來讀取它們;然而,在查看代碼時,它可能會更新「ProtoReader.position」和「ProtoReader.blockEnd」爲「long」,並確保將相關的「int.MaxValue」更改爲「long」。 MaxValue'。你可能在某處有一個示例生成器或示例嗎?我當然可以嘗試編寫一個多GB的生成器,但在詢問時沒有任何傷害... –

+0

害怕我不知道,代碼(和數據)屬於我的僱主。我想在此期間我會重新生成並將文件分成更小的塊。 – geekchic