Jonas Bartkowski
Jonas Bartkowski

Reputation: 387

How to convert binary text into useable file

So I use the following methods

(File is converted to Byte Array through 'convertFileToByteArray()', then written to .txt file by 'convertByteArrayToBitTextFile()'

to convert any kind of file into a Binary Text file (and by that I mean only 1's and 0's in human readable form.)

public static byte[] convertFileToByteArray(String path) throws IOException
{
    File file = new File(path);
    byte[] fileData;
    fileData = new byte[(int)file.length()];
    FileInputStream in = new FileInputStream(file);
    in.read(fileData);
    in.close();
    return fileData;
}

public static boolean convertByteArrayToBitTextFile(String path, byte[] bytes)
{
    String content = convertByteArrayToBitString(bytes);
    try
    {
        PrintWriter out = new PrintWriter(path);
        out.println(content);
        out.close();
        return true;
    }
    catch (FileNotFoundException e)
    {
        return false;
    }
}

public static String convertByteArrayToBitString(byte[] bytes)
{
    String content = "";
    for (int i = 0; i < bytes.length; i++)
    {
        content += String.format("%8s", Integer.toBinaryString(bytes[i] & 0xFF)).replace(' ', '0');
    }
    return content;
}

Edit: Additional Code:

public static byte[] convertFileToByteArray(String path) throws IOException
{
    File file = new File(path);
    byte[] fileData;
    fileData = new byte[(int)file.length()];
    FileInputStream in = new FileInputStream(file);
    in.read(fileData);
    in.close();
    return fileData;
}

public static boolean convertByteArrayToBitTextFile(String path, byte[] bytes)
{
    try
    {
        PrintWriter out = new PrintWriter(path);
        for (int i = 0; i < bytes.length; i++)
        {
            out.print(String.format("%8s", Integer.toBinaryString(bytes[i] & 0xFF)).replace(' ', '0'));
        }
        out.close();
        return true;
    }
    catch (FileNotFoundException e)
    {
        return false;
    }
}

public static boolean convertByteArrayToByteTextFile(String path, byte[] bytes)
{
    try
    {
        PrintWriter out = new PrintWriter(path);
        for(int i = 0; i < bytes.length; i++)
        {
            out.print(bytes[i]);
        }
        out.close();
        return true;
    }
    catch (FileNotFoundException e)
    {
        return false;
    }
}

public static boolean convertByteArrayToRegularFile(String path, byte[] bytes)
{
    try
    {
        PrintWriter out = new PrintWriter(path);
        for(int i = 0; i < bytes.length; i++)
        {
            out.write(bytes[i]);
        }
        out.close();
        return true;
    }
    catch (FileNotFoundException e)
    {
        return false;
    }
}

public static boolean convertBitFileToByteTextFile(String path) 
{
    try
    {
        byte[] b = convertFileToByteArray(path);
        convertByteArrayToByteTextFile(path, b);
        return true;
    }
    catch (IOException e)
    {
        return false;
    }

}

I do this to try methods of compression on a very fundamental level, so please let's not discuss why use human-readable form.

Now this works quite well so far, however I got two problems.

1) It takes foreeeever (>20 Minutes for 230KB into binary text). Is this just a by-product of the relatively complicated conversion or are there other methods to do this faster?

2) and main problem: I have no idea how to convert the files back to what they used to be. Renaming from .txt to .exe does not work (not too surprising as the resulting file is two times larger than the original)

Is this still possible or did I lose Information about what the file is supposed to represent by converting it to a human-readable text file? If so, do you know any alternative that prevents this?

Any help is appreciated.

Upvotes: 0

Views: 5423

Answers (2)

Ingo
Ingo

Reputation: 36339

The thing that'll cost you most time is the construction of an ever increasing String. A better approach would be to write the data as soon as you have it.

The other problem is very easy. You know that every sequence of eight characters ('0' or '1') was made from a byte. Hence, you know the values of each character in an 8-character block:

01001010
       ^----- 0*1
      ^------ 1*2
     ^------- 0*4
    ^-------- 1*8
   ^--------- 0*16
  ^---------- 0*32
 ^----------- 1*64
^------------ 0*128
              -----
              64+8+2 = 74

You only need to add the values where an '1' is present.

You can do it in Java like this, without even knowing the individual bit values:

String sbyte = "01001010";
int bytevalue = 0;
for (i=0; i<8; i++) {
    bytevalue *= 2;           // shifts the bit pattern to the left 1 position
    if (sbyte.charAt(i) == '1') bytevalue += 1;
}

Upvotes: 3

SLaks
SLaks

Reputation: 887375

  1. Use StringBuilder to avoid generating enormous numbers of unused String instances.
    Better yet, write directly to the PrintWriter instead of building it in-memory at all.

  2. Loop through every 8-character subsequence and call Byte.parseByte(text, 2) to parse it back to a byte.

Upvotes: 2

Related Questions