none
Read hex data from binary file

    Question

  • Here is my problem:

    I have a file in binary format.
    When i open it with an hex editor i get

    0000000         34 6D 0D 37 C9 69  99  3E-35 1A FF         4.m.7.i.>5...

    when i open this with notepad, i get

    4m
    7Éi™>5ÿ

    The data, i assume is in a binary format. these represent some decimal numbers, that am supposed to
    read.

    After a long day of sifting and tryouts, i couldn't do anything usable, so am asking you guys.

    How can i read that hex data and turn it into numbers or usable ascii strings?


    Thursday, April 30, 2009 12:53 PM

Answers

  • Reading Binary file

    /// <summary>
    /// Reads data from a stream until the end is reached. The
    /// data is returned as a byte array. An IOException is
    /// thrown if any of the underlying IO calls fail.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    /// <param name="initialLength">The initial buffer length</param>
    public static byte[] ReadFully (Stream stream, int initialLength)
    {
        // If we've been passed an unhelpful initial length, just
        // use 32K.
        if (initialLength < 1)
        {
            initialLength = 32768;
        }
        
        byte[] buffer = new byte[initialLength];
        int read=0;
        
        int chunk;
        while ( (chunk = stream.Read(buffer, read, buffer.Length-read)) > 0)
        {
            read += chunk;
            
            // If we've reached the end of our buffer, check to see if there's
            // any more information
            if (read == buffer.Length)
            {
                int nextByte = stream.ReadByte();
                
                // End of stream? If so, we're done
                if (nextByte==-1)
                {
                    return buffer;
                }
                
                // Nope. Resize the buffer, put in the byte we've just
                // read, and continue
                byte[] newBuffer = new byte[buffer.Length*2];
                Array.Copy(buffer, newBuffer, buffer.Length);
                newBuffer[read]=(byte)nextByte;
                buffer = newBuffer;
                read++;
            }
        }
        // Buffer is now too big. Shrink it.
        byte[] ret = new byte[read];
        Array.Copy(buffer, ret, read);
        return ret;
    }
    

    Converting Byte Array to Hex String


    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);
    
    }

    Hex to decimal

    // Store integer 182
    int decValue = 182;
    // Convert integer 182 as a hex in a string variable
    string hexValue = decValue.ToString("X");
    // Convert the hex string back to the number
    int decAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);


    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    • Marked as answer by Serg.JN Thursday, April 30, 2009 3:17 PM
    Thursday, April 30, 2009 1:39 PM

All replies

  • Reading Binary file

    /// <summary>
    /// Reads data from a stream until the end is reached. The
    /// data is returned as a byte array. An IOException is
    /// thrown if any of the underlying IO calls fail.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    /// <param name="initialLength">The initial buffer length</param>
    public static byte[] ReadFully (Stream stream, int initialLength)
    {
        // If we've been passed an unhelpful initial length, just
        // use 32K.
        if (initialLength < 1)
        {
            initialLength = 32768;
        }
        
        byte[] buffer = new byte[initialLength];
        int read=0;
        
        int chunk;
        while ( (chunk = stream.Read(buffer, read, buffer.Length-read)) > 0)
        {
            read += chunk;
            
            // If we've reached the end of our buffer, check to see if there's
            // any more information
            if (read == buffer.Length)
            {
                int nextByte = stream.ReadByte();
                
                // End of stream? If so, we're done
                if (nextByte==-1)
                {
                    return buffer;
                }
                
                // Nope. Resize the buffer, put in the byte we've just
                // read, and continue
                byte[] newBuffer = new byte[buffer.Length*2];
                Array.Copy(buffer, newBuffer, buffer.Length);
                newBuffer[read]=(byte)nextByte;
                buffer = newBuffer;
                read++;
            }
        }
        // Buffer is now too big. Shrink it.
        byte[] ret = new byte[read];
        Array.Copy(buffer, ret, read);
        return ret;
    }
    

    Converting Byte Array to Hex String


    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);
    
    }

    Hex to decimal

    // Store integer 182
    int decValue = 182;
    // Convert integer 182 as a hex in a string variable
    string hexValue = decValue.ToString("X");
    // Convert the hex string back to the number
    int decAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);


    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    • Marked as answer by Serg.JN Thursday, April 30, 2009 3:17 PM
    Thursday, April 30, 2009 1:39 PM
  • If you are confident you know the layout of the binary data in the file then a way I use is...

    Create a MemoryStream the same size as the file.
    Read all the bytes from the file into the Memorystream.
    Overlay a BinaryReader on top of the MemoryStream.
    Read data from the BinaryReader and do stuff with it.
        Eg. place it in Arrays or whatever.

    BinaryReader is your friend.

    So, Lets say your file was called data.dat.
    And, lets say that you'll be expecting the data files to come from 'Rose', 'John' & Bob. And they have respective uint32 id's that may inhabit the first 4 bytes of the file. After that you are expecting 10 floats.
    For example...

    FileInfo fi = new FileInfo("data.dat");
    MemoryStream ms = new MemoryStream((int)fi.length);
    ms.Write(File.ReadAllBytes(fi.FullName), 0, (int)fi.Length);
    BinaryReader br = new BinaryReader(ms);
    uint FileId = br.ReadUInt32(); //Rose=1, John=2, Bob=3
    float[] Floats = new float[10];
    int i=0;
    while (i<10)
    {
        Floats[i++] = br.ReadSingle();
    }
    

    The thing you should deduce first up is whether the incomming data is is BigEndian or LittleEndian format. As this will impact on the values you expect to get from BinaryReader.
    • Edited by Synide Friday, May 01, 2009 4:49 AM
    Thursday, April 30, 2009 9:05 PM
  • 4m
    7Éi™>5ÿ

    I want to explain why you get this. Notepad is designed to display only printable characters which are ASCII characters in the range between 32 and 128. There are some pritnable characters beyond that but they are "weird" and some of them you can see in that string for instance that E with an accent. Also you got a character that did carriage return and that is 0D (13). It broke the first line after two initial characters. Occasionally you can hear beeps and that is ASCII 7. In total it is gibberish. You cannot do much about them in this representation.

    You can run a simple app with a function like this:

    for ( int jj = 0; jj < 255;  jj++ )
    {
         Console.WriteLine ( (char)(byte)jj );
    }

    You will get ALL characters from 0 to 255 which is FF. keep it in mind that you will get empty spaces in many cases after ASCII 128.
    AlexB
    Friday, May 01, 2009 1:04 AM