Самый эффективный способ преобразования InputStream в байт []?
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
ArrayList<Byte> arrayList = new ArrayList<Byte>();
try {
while (responseStream.available() > 0) {
arrayList.add(responseStream.readByte());
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
Iterator<Byte> iterator = arrayList.iterator();
byte[] bytes = new byte[arrayList.size()];
int i = 0;
while (iterator.hasNext()) {
bytes[i++] = iterator.next();
}
Этот код вызывается при каждой загрузке страницы моего веб-приложения. Кажется, он работает довольно быстро, но есть ли что-нибудь, что могло бы ускорить этот запуск?
Редактировать - обновляется с использованием потока байтов массива
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
int read = responseStream.read();
while (read != -1) {
byteArrayOutputStream.write(read);
read = responseStream.read();
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
byte[] bytes = byteArrayOutputStream.toByteArray();
return ok(bytes).as(response.getHeader("Content-type"));
Изменить - тестовый тестовый код
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
long t1 = System.nanoTime();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
int read = responseStream.read();
while (read != -1) {
byteArrayOutputStream.write(read);
read = responseStream.read();
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
byte[] bytes = byteArrayOutputStream.toByteArray();
long t2 = System.nanoTime();
System.out.println(t2-t1);
return ok(bytes).as(response.getHeader("Content-type"));
Среднее время после запроса 100+ - 46873
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
long t1 = System.nanoTime();
ArrayList<Byte> arrayList = new ArrayList<Byte>();
try {
while (responseStream.available() > 0) {
arrayList.add(responseStream.readByte());
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
Iterator<Byte> iterator = arrayList.iterator();
byte[] bytes = new byte[arrayList.size()];
int i = 0;
while (iterator.hasNext()) {
bytes[i++] = iterator.next();
}
long t2 = System.nanoTime();
System.out.println(t2-t1);
return ok(bytes).as(response.getHeader("Content-type"));
Среднее время после запроса 100+ - 522848
long t1 = System.nanoTime();
byte[] bytes;
try {
bytes = org.apache.commons.io.IOUtils.toByteArray(responseStream);
} catch (Exception e) {
return internalServerError();
}
long t2 = System.nanoTime();
System.out.println(t2-t1);
Среднее время после запроса 100+ - 45088
long t1 = System.nanoTime();
byte[] bytes;
try {
bytes = sun.misc.IOUtils.readFully(responseStream, -1, true);
} catch (Exception e) {
return internalServerError();
}
long t2 = System.nanoTime();
System.out.println(t2 - t1);
Среднее время после запроса 100+ - 20180
Ответы
Ответ 1
Да. Используйте ByteArrayOutputStream
а не ArrayList. Затем прочитайте фрагменты байтов из InputStream (без использования available()
, которые почти никогда не будут использоваться) и напишите эти куски в ByteArrayOutputStream, пока метод read()
вернет -1. Затем вызовите toByteArray() в ByteArrayOutputStream
.
Вы можете использовать метод Guava ByteStreams.toByteArray()
, который делает все это для вас, или вы можете прочитать его исходный код, чтобы лучше понять, как он это делает. Чтение учебника IO также может помочь.
Ответ 2
Что случилось с методом Apache Commons IO IOUtils.toByteArray? Для этой цели это было оптимизировано на протяжении многих лет.
Ответ 3
Зачем? Этот код полностью эквивалентен read(byte[])
за исключением того, что он выполняет два дополнительных этапа копирования для всех данных. Тебе это не нужно. Простое read(byte[])
будет в несколько раз быстрее.
Использование available()
недействительно. Вам нужен весь ответ, а не только часть, которую можно прочитать без блокировки. Вам нужно зациклиться.