I'm looking for the value in a binary file, and its location is in the inde开发者_如何学JAVAx of the binary file. I'm using the following code, and its not getting me the right bytes back out of the binary file.
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();
I'm getting the correct value from the first read, at 0xC
, but I'm not converting the offset right. I tried converting it to a string first and getting the right string value, but the moment I try to get it to long its searching the wrong area. Also note that the data I need is actually ox60
BEFORE the index location given to me in the binary.
Yes, this is definitely the problem:
for (int x = 0; x < byErr.Length; x++)
{
offset = System.Convert.ToInt64(b[x].ToString());
}
You're converting each byte of the index individually to a string, then parsing it and assigning it to offset
. So only the last byte is actually going to be used.
You can try:
long offset = br.ReadInt32();
instead of calling ReadBytes(4)
to start with. If that uses the wrong endianness, you can use my EndianBinaryReader
class from MiscUtil.
You should log some diagnostic information to show what index you've read, and compare that with what you expect.
I'd also advise you to change your seeking code to:
fileStream.Position = offset - 60;
for simplicity. Additionally, flushing the file stream you're reading from and setting b
to null are unnecessary, and you should use a using
statement for your FileStream
, at which point you don't need to manually close anything.
Well I found this using google, http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ab831d92-14ad-437e-9b03-102d90f44d22/ and got it to work for what I needed. I'm converting from byte to string to long, so it seems like its definitely not the most efficient way, but it works perfectly. I also realized that .Position and .Seek were asking for a decimal value when I was trying to give it a hex offset.
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);
}
So now MY code looks like this....
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);
}
精彩评论