servlet octet from files application java java-ee servlets inputstream outputstream

java - octet - Escribir un InputStream a un HttpServletResponse



java download file from server (3)

Tengo un InputStream que quiero escribir en una HttpServletResponse. Existe este enfoque, que lleva demasiado tiempo debido al uso del byte []

InputStream is = getInputStream(); int contentLength = getContentLength(); byte[] data = new byte[contentLength]; is.read(data); //response here is the HttpServletResponse object response.setContentLength(contentLength); response.write(data);

Me preguntaba cuál podría ser la mejor manera de hacerlo, en términos de velocidad y eficiencia.


Creo que está muy cerca de la mejor manera, pero sugeriría el siguiente cambio. Use un búfer de tamaño fijo (Say 20K) y luego haga la lectura / escritura en un ciclo.

Para el bucle hacer algo como

Byte buffer[]=new byte[20*1024]; outputStream=response.getOutputStream(); while(true) { int readSize=is.read(buffer); if(readSize==-1) break; outputStream.write(buffer,0,readSize); }

ps: Tu programa no siempre funcionará como está, porque la lectura no siempre llena la matriz completa que le das.


Simplemente escriba en bloques en lugar de copiarlo por completo en la memoria de Java primero. El siguiente ejemplo básico lo escribe en bloques de 10KB. De esta manera, terminará con un uso de memoria consistente de solo 10 KB en lugar de la longitud completa del contenido. Además, el usuario final comenzará a recibir 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 con respecto al rendimiento, puede utilizar Channels NIO y un ByteBuffer asignado directamente. Cree el siguiente método de utilidad / ayuda en alguna clase de utilidad personalizada, por ejemplo, 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 usas de la siguiente manera:

response.setContentLength(getContentLength()); Utils.stream(getInputStream(), response.getOutputStream());


BufferedInputStream in = null; BufferedOutputStream out = null; OutputStream os; os = new BufferedOutputStream(response.getOutputStream()); in = new BufferedInputStream(new FileInputStream(file)); out = new BufferedOutputStream(os); byte[] buffer = new byte[1024 * 8]; int j = -1; while ((j = in.read(buffer)) != -1) { out.write(buffer, 0, j); }