【问题标题】:Using ListView to read binary file使用 ListView 读取二进制文件
【发布时间】:2012-09-11 14:54:25
【问题描述】:

我制作了这个包含列表视图的 exe,所以当我打开二进制文件时,它会在一列中显示文本指针,在另一列中显示文本字符串。

我设法显示指针,使用“for循环”,但我不知道如何使用循环显示文本字符串,所以我想使用的是循环指针,显示它指向的文本,并在每个文本之后停止在 00 00。

here 是二进制文件结构的示例。

二进制文件的前4个字节是指针/字符串数量,接下来的4个字节*第1个4个字节是指针,其余是文本字符串,每个字符串用00 00分隔,都是Unicode。

那么任何人都可以帮助我如何在字符串列中显示每个指针的字符串吗?

编辑:这是打开二进制文件的按钮的代码:

        private void menuItem8_Click(object sender, EventArgs e)
    {
        textBox1.Text = "";
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Title = "Open File";
        ofd.Filter = "Data Files (*.dat)|*.dat|All Files (*.*)|*.*";
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            MessageBox.Show("File opened Succesfully!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            path = ofd.FileName;
            BinaryReader br = new BinaryReader(File.OpenRead(path));               
            int num_pointers = br.ReadInt32();
            textBox1.Text = num_pointers.ToString();
            for (int i = 0; i < num_pointers; i++)
            {
                br.BaseStream.Position = i * 4 + 4;
                listView1.Items.Add(br.ReadUInt32().ToString("X"));
            }
            br.Close();
            br = null;
        }
        ofd.Dispose();
        ofd = null;
    }

【问题讨论】:

  • 花时间和麻烦在此处发布您的代码(相关部分)。
  • 添加了代码,如果你需要什么,请评论。
  • 您是否发现将字节数组转换为字符串很困难?
  • 是的,尤其是当有很多字符串时,我只需要一种方法来遍历指针列,并在第二列中显示每个指针指向的字符串。谢谢。

标签: c# .net file listview binary


【解决方案1】:

首先,在实例化 BinaryReader 时提供编码,如下所示:

BinaryReader br = new BinaryReader(File.OpenRead(path), Encoding.Unicode);

接下来,您要保留读取偏移量的列表。 (您仍然可以稍后将它们添加到 ListView):

List<int> offsets = new List<int>();
for (int i = 0; i < num_pointers; i++)
{
    // Note: There is no need to set the position in the stream as
    // the Read method will advance the stream to the next position
    // automatically.
    // br.BaseStream.Position = i * 4 + 4;
    offsets.Add(br.ReadInt32());
}

最后,您浏览偏移列表并从文件中读取字符串。您可能希望将它们放入一些数据结构中,以便稍后您可以使用数据填充视图:

Dictionary<int,string> values = new Dictionary<int,string>();
for (int i = 0; i < offsets.Count; i++)
{
    int currentOffset = offsets[i];

    // If it is the last offset we just read until the end of the stream
    int nextOffset = (i + 1) < offsets.Count ? offsets[i + 1] : (int)br.BaseStream.Length;

    // Note: Under the supplied encoding, a character will take 2 bytes.
    // Therefore we will need to divide the delta (in bytes) by 2.
    int stringLength = (nextOffset - currentOffset - 1) / 2;

    br.BaseStream.Position = currentOffset;

    var chars = br.ReadChars(stringLength);
    values.Add(currentOffset, new String(chars));
}

// Now populate the view with the data...
foreach(int offset in offsets)
{
    listView1.Items.Add(offset.ToString("X")).SubItems.Add(values[offset]);
}

【讨论】:

  • fs 没有声明,offsets.Add(br.ReadInt32()); 没有在列表视图的指针列中添加任何内容,所以我删除了br.BaseStream.Position = i * 4 + 4;,它按你说的那样工作谢谢,但仍然没有很好地获得第二个代码:s
  • 您可以将fs 替换为br.BaseStream.Length。 (我相应地更新了答案。)
  • 仍然无法正常工作:我将它们添加到按钮单击事件中,不是吗?它不显示字符串,谢谢您的时间:)
猜你喜欢
  • 2021-12-04
  • 2019-04-13
  • 2020-11-11
  • 2019-09-25
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多