Simplemente escriba en bloques en lugar de copiarlo por completo en la memoria de Java primero. El ejemplo básico a continuación lo escribe en bloques de 10 KB. De esta forma, se obtiene un uso de memoria constante de solo 10 KB en lugar de la longitud completa del contenido. Además, el usuario final comenzará a obtener partes del contenido mucho antes.
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);
}
}
Como crema de la crema en relación con el rendimiento, se puede usar NIO Channels
y directamente asignado ByteBuffer
. Cree el siguiente método de utilidad/ayuda en alguna clase de utilidad personalizada, p. 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;
}
}
que luego se utiliza de la siguiente manera:
response.setContentLength(getContentLength());
Utils.stream(getInputStream(), response.getOutputStream());
Esperaba que pudiera haber otra forma, pero gracias de todos modos –
Muchas gracias BalusC, –
Por supuesto, muchos paquetes de utilidades ya tienen este método definido, así que una vez que comiences a usar Guava ... http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io /ByteStreams.html#copy(java.io.InputStream, java.io.OutputStream) –