我有一个程序将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)**
答案 0 :(得分:1)
我会使用BinaryReader来读取部分文件并将每个部分添加到stringbuilder中,而不是一次读取整个文件并将其转换为字符串。
答案 1 :(得分:1)
那么就不要喂BitConverter.ToString
这样大的数组。比如每次1 MB就可以了。
例如,使用BinaryReader
。
答案 2 :(得分:0)
您是否考虑过流媒体?这取决于你想要对该字符串做什么,如果你发送它,这是最有可能的情况,当你可以发送它的小部分,这是流。一些协议实现也允许构建一个chuck并刷新它,所以我建议这样做。
在您的情况下,您只能读取文件的某些部分,然后进行分析。 Checkout BinaryReader,FileStream类和流媒体
答案 3 :(得分: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();
然而,请注意关于这么大的字符串的用处的评论。最好的解决方案实际上可能是根本不创建整个字符串。