Преобразование байтового массива в строку (Java) - PullRequest
85 голосов
/ 15 апреля 2011

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

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

Вот моя единственная проблема сейчас:

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

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

Ответы [ 7 ]

141 голосов
/ 15 апреля 2011

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

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

Кстати - необработанные байты могут отображаться как отрицательные десятичные числа только потому, что тип данных 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")); 
25 голосов
/ 04 марта 2015

Java 7 и выше

Вы также можете передать желаемую кодировку в конструктор String в виде константы Charset из StandardCharsets .Это может быть безопаснее, чем передавать кодировку как String, как предлагается в других ответах.

Например, для кодировки UTF-8

String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
11 голосов
/ 08 января 2013

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

String s = new String(bytearray);
5 голосов
/ 09 июля 2013
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
}
5 голосов
/ 15 апреля 2011
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
4 голосов
/ 21 июня 2015

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

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

3 голосов
/ 15 апреля 2011

Предыдущий ответ от 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.

...