Prev: 443413 M3i Zero , Ezflash Dsi , R4i Dsi 43531
Next: Can I get the Mime Content Type from a byte array?
From: Michelle on 14 Sep 2009 08:40 I've tried to write code to read the previous four bytes. This is my code: static void FindPrevBytes(int ioffset) { FileStream fs = File.OpenRead(@"D:\myfile.bin"); // opens the file for reading BinaryReader br = new BinaryReader(fs); br.BaseStream.Position = ioffset - 4; // position = offset pattern found -4 bytes byte[] arrBytes = br.ReadBytes(4); // array containing the four bytes string strBytes = (Regex.Replace(BitConverter.ToString(arrBytes), "-", "")); // string output WITHOUT dashes. int intDecValue = int.Parse(strBytes, System.Globalization.NumberStyles.HexNumber); // convert Hex to Dec Console.WriteLine("Value found: " + intDecValue ); // write } I'm not happy about this; FileStream fs = File.OpenRead(@"D:\myfile.bin"); Because it opens the file for reading the second time. It works, but I'm not sure this is the best solution. Please give me feedback. Best regards, Michelle
From: Peter Duniho on 14 Sep 2009 13:05 On Mon, 14 Sep 2009 05:40:08 -0700, Michelle <michelle(a)notvalid.nomail> wrote: > [...] > I'm not happy about this; FileStream fs = > File.OpenRead(@"D:\myfile.bin"); > Because it opens the file for reading the second time. > It works, but I'm not sure this is the best solution. > Please give me feedback. The only reason to use BinaryReader is if you want to convert directly from bytes read to some more complex type. If you're only ever going to read the plain bytes, just read them directly from the FileStream you're working with. You can use the Position property to adjust from where you're reading in the file; save the current position, set the current position to 4 bytes earlier than the offset of the found string, read the 4 bytes of interest, then restore the current position to the previously saved value. Your processing of those four bytes seems odd too, but perhaps we just don't know enough about the format. If you have 4 bytes in an array, it would seem that you ought to just be using BitConverter to convert those directly to a 32-bit int, rather than doing all that stuff with the string. If, as it appears from your conversion code, the bytes in the file are big-endian (most-significant-byte first) you can handle that much more cleanly simply by swapping the bytes before converting to a 32-bit int. If you like, you can just encapsulate that in a single method: int Int32FromMSBArray(byte[] rgb) { byte bT = rgb[0]; rgb[0] = rgb[3]; rgb[3] = bT; bT = rgb[1]; rgb[1] = rgb[2]; rgb[2] = rgbT; return BitConverter.ToInt32(rgb, 0); } (The above code modifies the input array; normally this shouldn't be a problem, but if you need the original array preserved, you'll want to make a copy). Pete
From: Peter Duniho on 14 Sep 2009 13:21 On Mon, 14 Sep 2009 10:05:15 -0700, Peter Duniho <no.peted.spam(a)no.nwlink.spam.com> wrote: > [...] > (The above code modifies the input array; normally this shouldn't be a > problem, but if you need the original array preserved, you'll want to > make a copy). Or alternatively, just swap the bytes _after_ the conversion, using traditional bit-shift/or operations (the code's less obvious to some people, but it will be much more efficient). Pete
From: Michelle on 15 Sep 2009 03:02 Peter, > [ . . .] If you're only ever going to read the plain bytes, just read > them directly from the FileStream you're working with. You can use the > Position property to adjust from where you're reading in the file; save > the current position, set the current position to 4 bytes earlier than > the offset of the found string, read the 4 bytes of interest, then > restore the current position to the previously saved value. So I must use Get and Set using the FileStream.Position property. But how can I read the bytes from a specific position from the FileStream . I couldn't find that using the FileStream, so I'd used BinaryReader. > If, as it appears from your conversion code, the bytes in the file are > big-endian (most-significant-byte first) you can handle that much more > cleanly simply by swapping the bytes before converting to a 32-bit int. All I need is the Decimal value of these four bytes. I can't use BitConverter to convert an Array directly to Decimal. I can use a System.IO.MemoryStream object instead: //Create a decimal from a bye array. public static decimal ByteArrayToDecimal (byte[] src) { //Create a MemoryStream containing the byte array. using (MemoryStream stream = new MemoryStream(src)) { //Create a BinaryReader to read the decimal from the stream. using (BinaryReader reader = new BinaryReader(stream)) { // Read and return the decimal from the BinaryReader/MemoryStream return reader.ReadDecimal(); } } } Instead of that, I used: string strBytes = (Regex.Replace(BitConverter.ToString(arrBytes), "-", "")); // string output WITHOUT dashes. int intDecValue = int.Parse(strBytes, System.Globalization.NumberStyles.HexNumber); //convert to dec Best regards, Michelle
From: Peter Duniho on 15 Sep 2009 04:11
On Tue, 15 Sep 2009 00:02:57 -0700, Michelle <michelle(a)notvalid.nomail> wrote: > So I must use Get and Set using the FileStream.Position property. > But how can I read the bytes from a specific position from the > FileStream . > I couldn't find that using the FileStream, so I'd used BinaryReader. FileStream _only_ allows reading bytes, either one at a time or into a byte[]. As far as reading bytes from a specific position in the file, you have to set the Position property to the position where you want to read, and then you simply read. It's just that simple. >> If, as it appears from your conversion code, the bytes in the file are >> big-endian (most-significant-byte first) you can handle that much more >> cleanly simply by swapping the bytes before converting to a 32-bit int. > > All I need is the Decimal value of these four bytes. > I can't use BitConverter to convert an Array directly to Decimal. I don't really understand that. I mean, yes it's true...BitConverter doesn't provide support for reading or writing the Decimal type. But the code you posted before doesn't use the Decimal type anyway. > I can use a System.IO.MemoryStream object instead: > > //Create a decimal from a bye array. > public static decimal ByteArrayToDecimal (byte[] src) > { > //Create a MemoryStream containing the byte array. > using (MemoryStream stream = new MemoryStream(src)) > { > //Create a BinaryReader to read the decimal from the stream. > using (BinaryReader reader = new BinaryReader(stream)) > { > // Read and return the decimal from the BinaryReader/MemoryStream > return reader.ReadDecimal(); > } > } > } That looks like a fine way to convert a byte array to the Decimal numeric type. But if you've already got a FileStream, you should be able to use BinaryReader directly on it, and if the stored data in the file isn't actually in the Decimal numeric format, then reading it as Decimal isn't going to work anyway. Note that the Decimal numeric type takes up 16 bytes in a file. So if you are reading only 4 bytes, then obviously either you are reading the data as the wrong format, or not reading enough bytes. Either way, you won't get valid results. > Instead of that, I used: > > string strBytes = (Regex.Replace(BitConverter.ToString(arrBytes), "-", > "")); // string output WITHOUT dashes. > int intDecValue = int.Parse(strBytes, > System.Globalization.NumberStyles.HexNumber); //convert to dec Do you get the values you expect when you do that? If so, then your number must not be Decimal in the first place. Beyond that, as I mentioned before, the code above will parse your bytes as if they are big-endian. So if the data in the file isn't in big-endian format, that's also a problem. Again, the question is, do you get the values you expect? Basically, you've provided no information here that would allow anyone to know for sure what the format of the numbers in your file are. Unless and until you do so, no one can offer any specific advice as to how to read that data; we can only make assumptions based on code you've shown, including the assumption the code you've shown does what you want. Pete |