Ответ 1
Просто напишите в блоках, а не сначала скопируйте его в память Java. Следующий базовый пример записывает его в блоки по 10 КБ. Таким образом, вы получаете постоянное использование памяти всего 10 КБ вместо полной длины содержимого. Кроме того, конечный пользователь начнет получать части контента намного раньше.
response.setContentLength(getContentLength());
byte[] buffer = new byte[10240];
try (
InputStream input = getInputStream();
OutputStream output = response.getOutputStream();
) {
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
В качестве крема в отношении производительности вы можете использовать NIO Channels
и непосредственно выделенный ByteBuffer
. Создайте следующий метод утилиты/помощника в каком-либо специальном классе утилиты, например. Utils
:
public static long stream(InputStream input, OutputStream output) throws IOException {
try (
ReadableByteChannel inputChannel = Channels.newChannel(input);
WritableByteChannel outputChannel = Channels.newChannel(output);
) {
ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
long size = 0;
while (inputChannel.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
return size;
}
}
Что вы затем используете, как показано ниже:
response.setContentLength(getContentLength());
Utils.stream(getInputStream(), response.getOutputStream());