我有一個concat兩字節[]的問題。其中一個擁有超過300,000,000字節。這是拋出System.OutOfMemoryException
類型的例外。concat兩個字節[]返回System.OutOfMemoryException
我用這個代碼:
byte[] b3 = by2.Concat(by1).ToArray();
有人能幫助我
我有一個concat兩字節[]的問題。其中一個擁有超過300,000,000字節。這是拋出System.OutOfMemoryException
類型的例外。concat兩個字節[]返回System.OutOfMemoryException
我用這個代碼:
byte[] b3 = by2.Concat(by1).ToArray();
有人能幫助我
由於Concat
致電ToArray
對結果數組的大小不得而知。它無法創建適當的大數組,並只填充數據。因此,只要有更多的數據要填寫,它就會創建一個小的,然後當它滿了時,會一次又一次地創建兩倍大小的新的。這樣你需要更多的內存,然後只需理論(b1.Length + b2.Length) * 2
。而且事情變得更加棘手,因爲在某些點之後,這些大數組被分配在LOH上,並且不像GC那樣容易地將它們作爲普通對象收集起來。
這就是爲什麼你不應該在這種情況下使用ToArray()
並以舊式的方式來做:分配新的數組,其大小等於源數組的大小並複製數據。
喜歡的東西:
var b3 = new byte[b1.Length + b2.Length];
Array.Copy(b1, b2, b1.Length);
Array.Copy(b1, 0, b2, b1.Length, b2.Length);
它不保證成功,但使得它更容易。並執行很多很多,然後更快,然後ToArray()
。
只是一個小問題:問題不是「ToArray」。如果你看它的源代碼,你會發現它的行爲不同,如果源是「ICollection」(一個'byte []'也是'ICollection
@Dirk是的,你是對的。 'b1.ToArray()'可以很好的使用'b1.CopyTo'。我已經添加到我的答案。 – MarcinJuraszek
那麼,對於自身錯誤消息TAKS,你沒有的RAM可用連續〜550MB。也許它太分散了。
Yeha。儘管.....應該在64位應用程序上工作,但它並不是真的需要內存日誌,只是一個連續的區域,而64位應該在那裏。 – TomTom
嗯..你知道,從系統請求一個〜600meg的連續塊 - 我並不感到驚訝。它本身就是一個非常大的塊,並且假設你還必須在內存中有源數組,那就是超過1GB的原始數據塊。
你應該開始考慮其他數據結構
或試圖保持他們作爲文件並將它們映射到內存
編輯:memmapping整個文件需要在地址空間中相同的連續區域,所以它不會解決任何問題。這個答案將被刪除。
能否請你用示例代碼支持你的回答 – MaRiO
不,對不起。它很大程度上取決於你以後實際想要對數據做什麼**。最有可能的是,你並不真的「想要連接兩個300meg的數據」,僅僅是爲了獲得它的樂趣。你想粘上它,因爲你想稍後對它們做些什麼。例如,你想寫一個巨集到一個文件。或者,你想要從它們中計算出一些值。或者,你想把它看作一部電影,而不是兩部電影。等等。每一種最終的使用**都可能引導你去傳遞數據的許多其他方式,這樣**可以避免必須將它合併成巨大的數組。 – quetzalcoatl
例如,如果您想「將數據作爲整體傳遞給某個算法」,則可以嘗試使用IList
當處理這些數據時,我認爲你應該使用流(這當然取決於應用程序)。
然後,您可以擁有處理數據的代碼,而不需要將所有數據同時加載到內存中,也可以創建專用的流類作爲兩個流之間的串聯。
你可以請示例代碼支持你的答案 – MaRiO
你連接磁盤上的兩個文件?或者這些字節數組從哪裏填充? – Magnus