Я пишу веб-приложение в Google App Engine. Он позволяет людям в основном редактировать html-код, который сохраняется в виде .html
файла в хранилище blobstore.
Я использую fetchData для возврата byte[]
всех символов в файле. Я пытаюсь распечатать HTML-код, чтобы пользователь мог отредактировать HTML-код. Все отлично работает!
Вот теперь моя единственная проблема:
У байтового массива возникают проблемы при преобразовании обратно в строку. Умные цитаты и пара персонажей выглядят напуганными. (? или японские символы и т. д.) В частности, я вижу несколько байтов с отрицательными значениями, которые вызывают проблему.
Умные цитаты возвращаются , как -108
и -109
в массиве байт. Почему это так и как я могу декодировать отрицательные байты, чтобы показать правильную кодировку символов?
InputStream
а затем в негоbyte[]
. Теперь, когда я пытаюсь преобразоватьbyte[]
в String (мне нужно использовать тело ответа для атак), я получаю действительно забавные символы, полные умных кавычек, вопросительных знаков и прочего. Я считаю , что ваша проблема в том же , как у меня , как мы оба имеем дело сhtml
вbyte[]
. Вы можете посоветовать?String str=new String(buffer, "Cp1252");
но без помощи.Ответы:
Массив байтов содержит символы в специальной кодировке (которую вам следует знать). Способ преобразования его в строку:
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"));
источник
byte
тип данных Java подписан. «Отрицательные» значения - это просто байты с самым старшим набором байтов. Он также объясняет, какой наиболее вероятный набор символов вам следует использовать - Windows-1252. Однако вы должны знать, какой набор символов использовать из контекста или соглашения, без необходимости гадать.Java 7 и выше
Вы также можете передать желаемую кодировку
String
конструктору в видеCharset
константы из StandardCharsets . Это может быть безопаснее, чем передача кодировки как aString
, как предлагается в других ответах.Например, для кодировки UTF-8
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
источник
Вы можете попробовать это.
String s = new String(bytearray);
источник
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
источник
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 }
источник
read
исключение.Я предлагаю
Arrays.toString(byte_array);
Это зависит от вашей цели. Например, я хотел сохранить массив байтов в точном соответствии с форматом, который вы видите во время отладки, который выглядит примерно так:
[1, 2, 3]
если вы хотите сохранить точно такое же значение без преобразования байтов в символьный формат,Arrays.toString (byte_array)
сделайте это. Но если вы хотите сохранить символы вместо байтов, вы должны использоватьString s = new String(byte_array)
. В этом случаеs
равно эквиваленту[1, 2, 3]
в формате символа.источник
Предыдущий ответ от 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.
источник