Преобразование байтового массива в String (Java)

Я пишу веб-приложение в Google приложении Engine. Это позволяет людям в основном редактировать html-код, который хранится в файле .html в блочном хранилище.

Я использую fetchData для возврата byte[] всех символов в файле. Я пытаюсь распечатать html, чтобы пользователь мог редактировать html-код. Все отлично работает!

Здесь моя единственная проблема:

Байт-массив имеет некоторые проблемы при преобразовании обратно в строку. Умные кавычки и несколько персонажей выходят из фанки. (? или японские символы и т.д.) В частности, это несколько байтов, которые я вижу, которые имеют отрицательные значения, которые вызывают проблему.

Умные кавычки возвращаются как -108 и -109 в массив байтов. Почему это и как я могу декодировать отрицательные байты, чтобы показать правильную кодировку символов?

Ответ 1

Массив байтов содержит символы в специальной кодировке (которые вы должны знать). Способ преобразования его в строку:

String decoded = new String(bytes, "UTF-8");  // example for one encoding type

By the Way - необработанные байты могут отображаться как отрицательные десятичные знаки только потому, что тип данных java byte подписан, он охватывает диапазон от -128 до 127.


-109 = 0x93: Control Code "Set Transmit State"

Значение (-109) является непечатаемым управляющим символом в UNICODE. Таким образом, UTF-8 не является правильной кодировкой для этого символьного потока.

0x93 в "Windows-1252" - это "умная цитата", которую вы ищете, поэтому Java-имя этой кодировки - "Cp1252". Следующая строка содержит тестовый код:

System.out.println(new String(new byte[]{-109}, "Cp1252")); 

Ответ 2

Как и в Java 7, вы также можете передать нужную кодировку конструктору String в качестве константы Charset из StandardCharsets.

Это может быть безопаснее, чем передача кодировки как String, как это предложено в других ответах, и вы должны сделать это таким образом, если используете Java 7 или выше.

Пример для кодировки UTF-8

String bytesAsString = new String(bytes, StandardCharsets.UTF_8);

Ответ 3

Вы можете попробовать это.

String s = new String(bytearray);

Ответ 4

public class Main {

    /**
     * Example method for converting a byte to a String.
     */
    public void convertByteToString() {

        byte b = 65;

        //Using the static toString method of the Byte class
        System.out.println(Byte.toString(b));

        //Using simple concatenation with an empty String
        System.out.println(b + "");

        //Creating a byte array and passing it to the String constructor
        System.out.println(new String(new byte[] {b}));

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main().convertByteToString();
    }
}

Выход

65
65
A

Ответ 5

public static String readFile(String fn)   throws IOException 
{
    File f = new File(fn);

    byte[] buffer = new byte[(int)f.length()];
    FileInputStream is = new FileInputStream(fn);
    is.read(buffer);
    is.close();

    return  new String(buffer, "UTF-8"); // use desired encoding
}

Ответ 6

Я предлагаю Arrays.toString(byte_array);

Это зависит от вашей цели. Например, я хотел сохранить массив байтов точно так же, как формат, который вы можете видеть во время отладки, что-то вроде этого: [1, 2, 3] Если вы хотите сохранить точно такое же значение без преобразования байтов в формат символов, Arrays.toString (byte_array) делает это,. Но если вы хотите сохранить символы вместо байтов, вы должны использовать String s = new String(byte_array). В этом случае s равен эквиваленту [1, 2, 3] в формате символа.

Ответ 7

Предыдущий ответ от Andreas_D хорош. Я просто добавлю, что везде, где вы показываете вывод, там будет шрифт и кодировка символов, и он может не поддерживать некоторые символы.

Чтобы решить, является ли это проблемой Java или ваш дисплей, выполните следующие действия:

    for(int i=0;i<str.length();i++) {
        char ch = str.charAt(i);
        System.out.println(i+" : "+ch+" "+Integer.toHexString(ch)+((ch=='\ufffd') ? " Unknown character" : ""));
    }

Java будет отображать любые символы, которые он не может понять, 0xfffd для официального символа для неизвестных символов. Если вы видите '?' на выходе, но он не отображается в 0xfffd, это ваш экранный шрифт или кодировка, это проблема, а не Java.