我想创建一个十六进制编辑器来打开大型二进制文件。 这是我的代码。它适用于小文件。但是当我打开大文件时,Hex编辑器面临问题。
data[] ... array of byte
string str = "";
byte[] temp = null;
int i;
for (i = 0; i < (data.Length - 16); i += 16)
{
temp = _sub_array(data, i, 16);
str += BitConverter.ToString(temp).Replace("-", "\t");
str += "\n";
}
temp = _sub_array(data, i, (data.Length - i));
str += BitConverter.ToString(temp).Replace("-", "\t");
richTextBox.Text = str;
答案 0 :(得分:1)
正如评论中所说,你应该尽量避免在整个文件中阅读。但是,如果你需要一次在内存中的整个文件,我认为你的主要问题可能是&#34;粘性&#34;该程序将在阅读和转换数据时体验。您更明智地使用单独的线程进行十六进制工作,让主线程专注于保持UI平稳运行。无论哪种方式,您也可以使用任务而不是线程。因此,使用您的代码段,使其看起来更像这样:
data[] ... array of byte
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(readHexFile);
t.Start();
}
private void readHexFile()
{
string str = "";
byte[] temp = null;
int i;
for (i = 0; i < (data.Length - 16); i += 16)
{
temp = _sub_array(data, i, 16);
str += BitConverter.ToString(temp).Replace("-", "\t");
str += "\n";
}
temp = _sub_array(data, i, (data.Length - i));
str += BitConverter.ToString(temp).Replace("-", "\t");
BeginInvoke(new Action(()=> richTextBox.Text = str));
}
您需要使用System.Threading&#34;添加&#34;获得对线程的访问权限。另请注意,带有richTextBox.Text的BeginInvoke在lambda表达式中工作。当您在单独的线程上运行数据处理时,这是必要的,因为如果您尝试直接使用该线程访问文本框,Windows将抱怨跨线程调用。只允许进行控制的线程直接访问它。 BeginInvoke不直接访问控件,因此您可以从数据处理线程中使用它来获取写入控件的文本。这将阻止数据处理从&#34;胶粘&#34;用户界面响应。
如果你从来没有这样做,这可能看起来很吓人,但请相信我。如果您掌握了线程和任务(在机器内部不同但可以通过类似的开发人员工具进行操作),您将永远不希望再次从主线程渲染到UI。
编辑:我从代码中保留了字符串,但我同意建议使用StringBuilder的评论。字符串是不可变的,因此每次连接到字符串时,内部发生的事情是整个字符串被废弃,而新的字符串正在使用附加文本。所以,是的,也要切换到StringBuilder对象。答案 1 :(得分:1)
所以你已经有了小文件的代码,但是你遇到了大文件的问题。你没有提到这些问题是什么,所以这里有一些猜测:
BASH_SOURCE
,那么您可能会遇到内存问题并可能抛出byte[]
OutOfMemoryException
。这不仅是一个记忆问题,也是一个表演问题(参考Jon Skeet的文章http://www.yoda.arachsys.com/csharp/stringbuilder.html)string
并返回16个长度_sub_array()
,这是另一个内存和性能问题。byte[]
(参见子弹2)。我认为这些是内存问题,因为我们不知道垃圾收集器什么时候会清理内存。
让我们来解决这些潜在的问题:
String.Replace()
的需求。查看FileStream类,一次读取16个字节。_sub_array()
将这16个字节放入BitConverter.ToString()
StringBuilder
(我的评论),但在您阅读完文件之前不要执行StringBuilder.AppendLine()
。< / LI>
String.Replace()
分配给StringBuilder
,如此(某人是RichTextBox
使用的变量名称):StringBuilder
希望这会有所帮助......