Тип данных для записи ASCII 0-255 в Java (ServletOutputStream) - PullRequest
0 голосов
/ 16 февраля 2012

У меня есть массив «результат», который содержит значения от 0 до 255.Первоначально я объявил его как byte [], но когда мне нужно записать 128, результат [i] получает значение -128, а в выходном файле записывается «€», которое в итоге читается как 8364.

какЯ вижу, что байт принимает только значения от -128 до 127, какой тип данных мне следует использовать для значений от 0 до 255 (без потери памяти)?

Должен ли я также изменить тип содержимого или добавить какой-либо заголовок набора символов?

Спасибо

res.setContentType("application/octet-stream"); 
res.setHeader("Content-Disposition","attachment;filename=output.js");
ServletOutputStream os = res.getOutputStream();
byte[] result=encode(req.getParameter("originalScript")); // Result[i]=-128 (should be 128)
os.write(result,0,result.length); // result[i] on output.js is written as "€" (8364)

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Вы запутались, смешав несколько понятий.

Прежде всего, int 128 совпадает с байтом -128 (int 255 == байт -1, 254 == -2, ..128 = -128).Байты подписаны , а информация знака находится в старшем бите.Ваша ошибка здесь в том, что вы не использовали правильный способ преобразования байтового значения обратно в int.Чтобы исправить это, используйте этот код:

b = (byte) 128;
int i = b & 0xff;
System.out.println(b);
System.out.println(i);

дает -128 и 128.

Далее: ASCII определен только для значений от 0 до 127. Это означает что-либо> 127является мусором, если вы не обращаетесь с ним осторожно.

Проблема в том, что вы читаете вывод вашего кода.Поскольку ASCII не может содержать значения> 127, что должен делать код чтения?

«output.js» звучит так, как будто вы используете веб-браузер для чтения этих данных в виде файла JavaScript.Веб-браузер попытается преобразовать поток байтов в текст, используя «кодировку».Вы не указываете его, браузер должен угадать и ошибиться (и application/octet-stream тоже кажется неправильным. Разве это не должно быть text/javascript?).

У вас есть два варианта:

  1. Измените encode(), чтобы он возвращал правильно закодированную строку UTF-8 (UTF-8 - это способ отправки юникода в виде байтов) и установите для charset значение UTF-8 (обычно этопо умолчанию, но лучше быть безопасным, чем потом сожалеть):

    response.setHeader("Content-Type", "text/javascript; charset=UTF-8");
    
  2. Установите кодировку на ISO-8859-1, что сохранит байты 1: 1.Это не удастся, если ваш скрипт содержит какие-либо символы Unicode> 255. Поскольку ошибки не будет, вы должны , а не использовать этот подход.Я просто упомянул это для полноты.

1 голос
/ 16 февраля 2012

Трудно поверить, что ваше приложение предъявляет столь жесткие требования к памяти в наши дни.

Не подвергая сомнению ваши мотивы, вот что вы можете сделать:

byte[] result=encode(req.getParameter("originalScript"));
char[] tmp = new char[result.length];
for (int i = 0 ; i != result.length ; i++) {
    tmp[i] = (char)(result[i] & 0xFF);
}
os.print(new String(tmp));
...