用于打开大型二进制文件的Hex编辑器

时间:2015-08-03 20:50:50

标签: c# hex-editors

我想创建一个十六进制编辑器来打开大型二进制文件。 这是我的代码。它适用于小文件。但是当我打开大文件时,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;

2 个答案:

答案 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)。

我认为这些是内存问题,因为我们不知道垃圾收集器什么时候会清理内存。

让我们来解决这些潜在的问题:

  • 一次读取16个字节的文件(@EZI评论),这也消除了对String.Replace()的需求。查看FileStream类,一次读取16个字节。
  • _sub_array()将这16个字节放入BitConverter.ToString() StringBuilder(我的评论),但在您阅读完文件之前不要执行StringBuilder.AppendLine()。< / LI>
  • 阅读完文件后,您可以将String.Replace()分配给StringBuilder,如此(某人是RichTextBox使用的变量名称):StringBuilder

希望这会有所帮助......