2

I try to read the byte from "bytefile", changing it to String and store it to "stringfile". The code below is how I perform.

    PrintWriter writer = new PrintWriter(new FileOutputStream(new File("stringfile"), true));
    RandomAccessFile file = new RandomAccessFile("bytefile", "r");
    byte[] b = new byte[(int)file.length()];
    file.readFully(b);
    String str = new String(b, StandardCharsets.UTF_8);
    writer.write(str);
    writer.close();

Then I try to convert the string in "stringfile" to byte and store in "newbytefile". However, the outcome do not meet my expectation.

    String charset = "UTF-8";
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("stringfile"), charset));
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("newbytefile"), charset));
    String line;
    while ((line = reader.readLine()) != null){
        writer.println(line.getBytes());
    }
    reader.close();
    writer.close();

The pattern in "bytefile" is something like this:

<9e>zgóoG^P$@0<81>^B*É^X¿uú<9b>^@

The pattern in "stringfile" is something like this:

�zg�oG^P$@0�^B*�^X�u��^@�� V�

However, the pattern in "newbytefile" is something like this:

[B@40226788

How can I covert the string in "stringfile" to byte that is same to the original patten in "bytefile"?

wcke123
  • 37
  • 3
  • how to convert array to string: http://stackoverflow.com/questions/409784/whats-the-simplest-way-to-print-a-java-array – Jaroslaw Pawlak Apr 04 '17 at 14:20
  • `writer.println(line.getBytes());` actually calls `println(Object)`, which then calls the default `toString` of `Object` . – Arnaud Apr 04 '17 at 14:22

4 Answers4

2

The problem is: PrintWriter has no method to write an array of byte[].

So, when you call println(getBytes()) ... the compiler tries to find the matching overloaded method. It will find println(Object) (because: in the end, any java array is also an Object).

You can see that using the javap disassembler:

invokevirtual #22 // Method java/io/PrintWriter.println:(Ljava/lang/Object;)V

And within that method, toString() is called on the incoming object. And when you call toString() on an byte array, you get a result looking like "[B...." - see here for why that is.

In other words: because of overloading, you are not printing the byte array itself, but the default string representation of that byte array.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • `println(String)` is only called if you pass a String reference to it. – Peter Lawrey Apr 04 '17 at 14:22
  • 1
    It uses the println(Object) method which implicitly calls the toString method on the array giving it the address of the array – Daniel Bickler Apr 04 '17 at 14:23
  • Just to be absolutely clear to others with less java experience, could you maybe move the "compiler decides to use println(Object)" bit above the explanation of how it gets converted to a String. Just so that others who read the answer don't see it gets converted to a String and wonder why it doesn't use the println(String) overload? – Daniel Bickler Apr 04 '17 at 14:26
0

Some things you should note:

  • files are always a stream of bytes. You can pretend they are text by assuming a particular encoding.
  • your first example doesn't use a particular encoding to write the PrintWriter so you are using the default, which you must use to read the file as well.
  • you already know how to read/write, encode and decode using a character encoding, you just need to do it consistently.
  • Object.toString() prints the type, an '@' and the identity hash code of the object. byte[] doesn't override this method which is why you see it as the code you do.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

You might also find your input data is causing a problem: it can't be encoded into a String properly.

If you run:

package au.com.redbarn.stackoverflow.convert_byte_to_string_to_byte;

import java.nio.charset.StandardCharsets;

public class NoFiles {

    public static void main(String[] args) {

        byte[] byteIn = {60, 57, 101, 62, 122, 103, -13, 111, 71, 94, 80, 36, 64, 48, 60, 56, 49, 62, 94, 66, 42, -55, 94, 88, -65, 117, -6, 60, 57, 98, 62, 94, 64};
        String s = new String(byteIn, StandardCharsets.UTF_8);
        byte[] byteOut = s.getBytes(StandardCharsets.UTF_8);
        System.out.println(byteOut);
    }
}

byteIn != byteOut

Maybe start with a byte array you know will convert to a string properly. What is it that you're actually trying to do?

Provided your byte array can be converted properly, this will work:

package au.com.redbarn.stackoverflow.convert_byte_to_string_to_byte;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class ConvertByteToStringToByte {

    public static void main(String[] args) {

        try {
            // Read bytes, write String.
            byte[] b = Files.readAllBytes(FileSystems.getDefault().getPath("bytefile-in"));
            String strOut = new String(b, StandardCharsets.UTF_8);

            try (PrintWriter pw = new PrintWriter("stringfile")){
                pw.println(strOut);
            }
            catch (IOException e) {
                throw (e);
            }

            // Read String, write bytes.
            List<String> strsIn = Files.readAllLines(FileSystems.getDefault().getPath("stringfile"));

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            for (String strIn : strsIn) {
                baos.write(strIn.getBytes(StandardCharsets.UTF_8));
            }

            Files.write(Paths.get("bytefile-out"), baos.toByteArray());         
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Peter Svehla
  • 54
  • 1
  • 4
-1

You are on the right track, you still need to convert the array of byte to String by constructing one with the right arguments:

new String(line.getBytes(), "UTF-8");

Keep in mind that there are multiple ways of converting a byte array to String.

Paul W.
  • 9
  • 3