1

Yes, I have read solutions for about 5 hours, none of them work. BitConverter just creates a blank string.

Basically what I'm doing is trying to create a level reader, which will read a levels contents via hex and eventually display it in a treeview. So the first thing I have to do is make a byte array in which I can edit the data, I've done that. However, now I want to display the data on the screen. To my knowledge you can't display a byte array on screen, you must first convert it to a string.

So that's what I'm trying to do:

        using (OpenFileDialog fileDialog = new OpenFileDialog())
        {
            if (fileDialog.ShowDialog() != DialogResult.Cancel)
            {
                textBox1.Text = fileDialog.FileName;
                using (BinaryReader fileBytes = new BinaryReader(new MemoryStream(File.ReadAllBytes(textBox1.Text))))
                {
                    string s = null;
                    int length = (int)fileBytes.BaseStream.Length;
                    byte[] hex = fileBytes.ReadBytes(length);
                    File.WriteAllBytes(@"c:\temp_file.txt", hex);
                }
            }
        }
    }

Note: i have removed my conversion attempts as nothing I have tried worked. Does anyone know how I could use this data and convert it to a string, and add it to a textbox? (I know how to do the latter, of course. It's the former that I'm having difficulties with.) If so, please provide examples.

I probably should have made myself more clear; I don't want to convert the byte to the corresponding character (i.e. if It is 0x43, I DON'T want to print 'C'. I want to print '43'.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Anteara
  • 729
  • 3
  • 14
  • 33
  • I suspect you don't know - but what text encoding does your binary file format use? – tomfanning Sep 11 '12 at 08:20
  • The problem is, we don't know which solutions you've tried. I.e. have you seen [this answer](http://stackoverflow.com/a/311179/15498)? Also, what's with wrapping a byte array in a memory stream in a binary reader, just to then convert back to a byte array? – Damien_The_Unbeliever Sep 11 '12 at 08:23
  • @Damien_The_Unbeliever - Both methods in the accepted answer actually work; but they only work for around 10kb files. Anything else and it takes far too long to be feasible. (over 1 minute to read). Any ideas? – Anteara Sep 11 '12 at 09:17

4 Answers4

3

You can convert your data to Hex:

  StringBuilder hex = new StringBuilder(theArray.Length * 2);
  foreach (byte b in theArray)
    hex.AppendFormat("{0:x2}", b);
  return hex.ToString();
Eden
  • 3,696
  • 2
  • 24
  • 24
  • +1. This will get you hex... usually done with fancier LINQ single statement :) but this one more readable for non-experts. – Alexei Levenkov Sep 11 '12 at 08:28
  • I tried to do this, and upon printing, all it prints is `System.Byte[]`. This is what I did: http://pastebin.com/XTJW2iAS read: `length` is defined in my original post. I probably did something wrong... – Anteara Sep 11 '12 at 08:40
  • Very simple... textBox2.Text = hex.ToString(); should be textBox2.Text = hex1.ToString(); hex1 instead of hex ... – Eden Sep 11 '12 at 08:56
  • Oh! >< Silly mistake. When I try and run it now, the GUI freezes, and it appears to be non-responsive. Perhaps it's because the processing is being done on the same thread, but I don't think it should even take long enough for it to momentarily pause; any ideas? Edit: yeah, it was freezing because it's on the same thread. – Anteara Sep 11 '12 at 09:06
  • yeah, it just seems to take too long to be feasible.. I just tried with another file and it took over 60 seconds. Any idea, did i Implement it wrong or is it just slow? – Anteara Sep 11 '12 at 09:10
  • How big is the file? Maybe you should consider an external component ? http://sourceforge.net/projects/hexbox/ – Eden Sep 11 '12 at 09:14
  • @Eden - The file is 2 Megabytes. – Anteara Sep 11 '12 at 09:38
2

Do you know in which encoding your byte array is stored?

You need Encoding.GetString method

Here is MSDN example

using System;
using System.IO;
using System.Text;

public class Example
{
   const int MAX_BUFFER_SIZE = 2048;
   static Encoding enc8 = Encoding.UTF8;

   public static void Main()
   {
      FileStream fStream = new FileStream(@".\Utf8Example.txt", FileMode.Open);
      string contents = null;

      // If file size is small, read in a single operation. 
      if (fStream.Length <= MAX_BUFFER_SIZE) {
         Byte[] bytes = new Byte[fStream.Length];
         fStream.Read(bytes, 0, bytes.Length);
         contents = enc8.GetString(bytes);
      }
      // If file size exceeds buffer size, perform multiple reads. 
      else {
         contents = ReadFromBuffer(fStream);
      }
      fStream.Close();
      Console.WriteLine(contents);
   }

   private static string ReadFromBuffer(FileStream fStream)
   {
        Byte[] bytes = new Byte[MAX_BUFFER_SIZE];
        string output = String.Empty;
        Decoder decoder8 = enc8.GetDecoder();

        while (fStream.Position < fStream.Length) {
           int nBytes = fStream.Read(bytes, 0, bytes.Length);
           int nChars = decoder8.GetCharCount(bytes, 0, nBytes);
           char[] chars = new char[nChars];
           nChars = decoder8.GetChars(bytes, 0, nBytes, chars, 0);
           output += new String(chars, 0, nChars);                                                     
        }
        return output;
    }
}
// The example displays the following output: 
//     This is a UTF-8-encoded file that contains primarily Latin text, although it 
//     does list the first twelve letters of the Russian (Cyrillic) alphabet: 
//      
//     А б в г д е ё ж з и й к 
//      
//     The goal is to save this file, then open and decode it as a binary stream.

EDIT

If you want to print out byte array in hex format, BitConverter is what you are looking form, here is MSDN example

// Example of the BitConverter.ToString( byte[ ] ) method. 
using System;

class BytesToStringDemo
{
    // Display a byte array with a name. 
    public static void WriteByteArray( byte[ ] bytes, string name )
    {
        const string underLine = "--------------------------------";

        Console.WriteLine( name );
        Console.WriteLine( underLine.Substring( 0, 
            Math.Min( name.Length, underLine.Length ) ) );
        Console.WriteLine( BitConverter.ToString( bytes ) );
        Console.WriteLine( );
    }

    public static void Main( )
    {
        byte[ ] arrayOne = {
             0,   1,   2,   4,   8,  16,  32,  64, 128, 255 };

        byte[ ] arrayTwo = {
            32,   0,   0,  42,   0,  65,   0, 125,   0, 197,
             0, 168,   3,  41,   4, 172,  32 };

        byte[ ] arrayThree = {
            15,   0,   0, 128,  16,  39, 240, 216, 241, 255, 
           127 };

        byte[ ] arrayFour = {
            15,   0,   0,   0,   0,  16,   0, 255,   3,   0, 
             0, 202, 154,  59, 255, 255, 255, 255, 127 };

        Console.WriteLine( "This example of the " +
            "BitConverter.ToString( byte[ ] ) \n" +
            "method generates the following output.\n" );

        WriteByteArray( arrayOne, "arrayOne" );
        WriteByteArray( arrayTwo, "arrayTwo" );
        WriteByteArray( arrayThree, "arrayThree" );
        WriteByteArray( arrayFour, "arrayFour" );
    }
}

/*
This example of the BitConverter.ToString( byte[ ] )
method generates the following output.

arrayOne
--------
00-01-02-04-08-10-20-40-80-FF

arrayTwo
--------
20-00-00-2A-00-41-00-7D-00-C5-00-A8-03-29-04-AC-20

arrayThree
----------
0F-00-00-80-10-27-F0-D8-F1-FF-7F

arrayFour
---------
0F-00-00-00-00-10-00-FF-03-00-00-CA-9A-3B-FF-FF-FF-FF-7F
*/
Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
  • +1. useful if source is text (also it does not seem to be the case from the question). – Alexei Levenkov Sep 11 '12 at 08:27
  • @AlexeiLevenkov, if we want to convert byte array to text, it should contains text bytes in any encoding, am I wrong? – Arsen Mkrtchyan Sep 11 '12 at 08:31
  • I have no idea what OP wants as "convert byte array to text"... but it sounds OP wants to have at least printable output (probably characters at least outside of 0-31 range). Your sample does not give printable output in most cases, not sure what do you mean "any encoding": if source was text and you pick wrong encoding - will get non usable output (or exception for invalid UTF8 sequences), if source was random sequence of bytes it can't be converted with any normal Encoding to printable text... – Alexei Levenkov Sep 11 '12 at 08:38
  • ahh, yes @AlexeiLevenkov, you are right, if we mean printable output my code is useless – Arsen Mkrtchyan Sep 11 '12 at 08:40
  • I probably should have made myself more clear; I don't want to convert the byte to the corresponding character (i.e. if It is 0x43, I DON'T want to print 'C'. I want to print '43'. – Anteara Sep 11 '12 at 09:53
1

First you just need to convert your bytes to something more useful, like UTF8 for example, and then you can get you string from it. Something like (in my case: iso-8859-1):

buf = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), Encoding.UTF8, buf);
tempString = Encoding.UTF8.GetString(buf, 0, count);
opewix
  • 4,993
  • 1
  • 20
  • 42
  • If source data was not a string it will not become much better after this... and also may simply throw as not every byte sequence is valid UTF8 sequence. – Alexei Levenkov Sep 11 '12 at 08:30
1

There is really no default way to display random byte sequence. Options:

  • base64 encode (Convert.ToBase64String) - will produce not readable, but at least safely printable string
  • HEX-encode each byte and concatenate with space between each byte's representation, potentially split into groups of several (i.e. 16) bytes per line. - will produce more hacker-like view.
  • map all bytes to printable characters (potentially colored) and possibly split in multiple lines - will produce Matrix-like view of data...
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179