从二进制文件中的索引获得偏移量

时间:2011-04-26 05:25:01

标签: c#

我正在寻找二进制文件中的值,它的位置在二进制文件的索引中。我正在使用以下代码,它没有从二进制文件中找到正确的字节。

long offset = 0;

//Open read stream
Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader brFile = new BinaryReader(fileStream);

//Read index to find start position
fileStream.Seek(0xC, SeekOrigin.Begin);
byte[] b = brFile.ReadBytes(4);

//Convert to long value
for (int x = 0; x < byErr.Length; x++)
    offset = System.Convert.ToInt64(b[x].ToString()); //I'm assuming this is the problem

//Cleanup
fileStream.Flush();
b = null;

//Read needed value
fileStream.Position = offset;
fileStream.Seek(-0x60, SeekOrigin.Current); //The value I need is 0x60 BEFORE the index location
b = brFile.ReadBytes(4);

//Cleanup
fileStream.Flush();
fileStream.Close();
brFile.Close();

我从0xC的第一次读取中得到了正确的值,但我没有将偏移量转换为正确的值。我尝试先将它转换为字符串并获得正确的字符串值,但是当我试图让它长时间搜索错误的区域时。另请注意,我需要的数据实际上是ox60在二进制文件中给我的索引位置之前。

2 个答案:

答案 0 :(得分:4)

是的,这绝对是问题所在:

for (int x = 0; x < byErr.Length; x++)
{
    offset = System.Convert.ToInt64(b[x].ToString());
}

您将索引的每个字节分别转换为字符串,然后解析它并将其分配给offset。因此,实际上只会使用最后一个字节。

您可以尝试:

long offset = br.ReadInt32();

而不是调用ReadBytes(4)开始。如果使用错误的字节顺序,则可以使用MiscUtil中的EndianBinaryReader类。

您应该记录一些诊断信息,以显示您已阅读的索引,并将其与您的预期进行比较。

我还建议您将寻求代码更改为:

fileStream.Position = offset - 60;

为简单起见。此外,刷新您正在阅读的文件流并将b设置为null是不必要的,您应该为using使用FileStream语句,此时您不需要手动关闭任何东西。

答案 1 :(得分:0)

好吧,我发现这是使用谷歌,http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ab831d92-14ad-437e-9b03-102d90f44d22/,并让它为我需要的工作。我正在从字节转换为字符串到长,所以看起来它绝对不是最有效的方式,但它完美地工作。我也意识到.Position和.Seek在我试图给它一个十六进制偏移时要求一个十进制值。

    public static string HexStr(byte[] p)
    {
        char[] c = new char[p.Length * 2 + 2];
        byte b;
        c[0] = '0'; c[1] = 'x';
        for (int y = 0, x = 2; y < p.Length; ++y, ++x)
        {
            b = ((byte)(p[y] >> 4));
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
            b = ((byte)(p[y] & 0xF));
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
        }
        return new string(c);
    }

所以现在我的代码看起来像这样......

        using (Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            BinaryReader brFile = new BinaryReader(fileStream);

            //Read index to find start position
            fileStream.Position = 0xC;
            byte[] offsetByte = brFile.ReadBytes(4);
            string offsetString = HexStr(offsetByte);
            long offset = System.Convert.ToInt64(offsetString, 16);

            //Read needed value
            fileStream.Position = offset - 96; //-0x60 translates to -96
            byte[] byVal = brFile.ReadBytes(4);
        }