2011-11-02 30 views
1

我有一個程序,一個byte []轉換爲十六進制的字符串:運行內存建設大規模串

byte[] bytes = File.ReadAllBytes(infile); 

try 
{ 
    StringBuilder sb = new StringBuilder(BitConverter.ToString(bytes)); // <--exception 
    hexfield.Text = sb.ToString(); 
} 

catch(Exception e) 
{ 
    MessageBox.Show(e.ToString()); 
} 

這工作適合大多數情況下。但是,當我用一個巨大的文件,例如一個103 MB的FLV視頻文件,它運行的內存,它拋出一個異常:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
at System.String.CtorCharArrayStartLength(Char[] value, Int32 startIndex, Int32 length) 
at System.BitConverter.ToString(Byte[] value, Int32 startIndex, Int32 length) 
at System.BitConverter.ToString(Byte[] value) 
at shex.shexx.hexfield_Dragrop(Object sender, DragEventArgs e)** 
+3

你需要怎樣處理累加的字節? – sll

+1

真正的課程問題是:爲什麼。您不可能有用地將該值分配給輸入控件(假設hexfield爲1)。你應該簡單地截斷它到有用的數額。 – sehe

+0

@sll與字節或十六進制字符串?問題是:''將字節[]轉換爲十六進制字符串的程序「' – StuperUser

回答

0

BitConverter.ToString方法首先創建一個char數組,然後從中創建一個字符串,所以在內存中需要兩次空間。

您可以將數據轉換爲較小的塊,然後使用初始大小創建StringBuilder,以便擁有所需的所有空間。這樣,大串在內存中僅存在一次:

StringBuilder b = new StringBuilder(bytes.Length * 3 - 1); 
int pos = 0; 
while (pos < bytes.Length - 1000) { 
    b.Append(BitConverter.ToString(bytes, pos, 1000)).Append('-'); 
    pos += 1000; 
} 
b.Append(BitConverter.ToString(bytes, pos)); 
hexfield.Text = b.ToString(); 

但是,請注意,從sehe這樣一個巨大的字符串的有用的評論。最好的解決方案實際上可能是根本不創建整個字符串。

0

你有沒有考慮過流,例如?這取決於你想用這個字符串做什麼,如果你發送的是最可能的場景,當你可以發送一小部分,這是流媒體的目的。一些協議實現也允許構建一個卡盤並沖洗它,所以我會建議這種方式去。

在你的情況下,你只能讀取文件的一部分,然後分析它。 Checkout BinaryReader,FileStream類和流媒體

1

我會使用BinaryReader讀取部分文件,並將每個部分添加到字符串生成器,而不是一次讀取整個文件並將其轉換爲字符串。

看一看this documentation

1

那麼不要喂BitConverter.ToString這樣的大型陣列。以每次1 MB的大塊爲單位進行操作。例如,使用BinaryReader