First: ISO-8859-1
does not cause any data loss if an arbitrary byte array is converted to string using this encoding. Consider the following program:
public class BytesToString {
public static void main(String[] args) throws Exception {
// array that will contain all the possible byte values
byte[] bytes = new byte[256];
for (int i = 0; i < 256; i++) {
bytes[i] = (byte) (i + Byte.MIN_VALUE);
}
// converting to string and back to bytes
String str = new String(bytes, "ISO-8859-1");
byte[] newBytes = str.getBytes("ISO-8859-1");
if (newBytes.length != 256) {
throw new IllegalStateException("Wrong length");
}
boolean mismatchFound = false;
for (int i = 0; i < 256; i++) {
if (newBytes[i] != bytes[i]) {
System.out.println("Mismatch: " + bytes[i] + "->" + newBytes[i]);
mismatchFound = true;
}
}
System.out.println("Whether a mismatch was found: " + mismatchFound);
}
}
It builds an array of bytes with all possible byte values, then it converts it to String
using ISO-8859-1
and then back to bytes using the same encoding.
This program outputs Whether a mismatch was found: false
, so bytes->String->bytes conversion via ISO-8859-1
yields the same data as it was in the beginning.
But, as it was pointed out in the comments, String
is not a good container for binary data. Specifically, such a string will almost surely contain unprintable characters, so if you print it or try to pass it via HTML or some other means, you will get some problems (data loss, for example).
If you really need to convert byte array to a string (and use it opaquely), use base64
encoding:
String stringRepresentation = Base64.getEncoder().encodeToString(bytes);
byte[] decodedBytes = Base64.getDecoder().decode(stringRepresentation);
It takes more space, but the resulting string is safe in regard to printing.