将InputStream写入HttpServletResponse

我有一个我想要写入HttpServletResponse的InputStream。 有这种方法,由于使用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); 

在速度和效率方面,我想知道最好的方法是什么。

只需要用块写入,而不是先将它完全复制到Java的内存中。 以下基本示例将其写入10KB的块中。 这样,您最终只能获得10KB的内存使用量,而不是完整的内容长度。 此外,最终用户将更快地开始获取部分内容。

 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); } } 

作为creme de la creme的性能,您可以使用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()); 
 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); } 

我认为这与最好的方式非常接近,但我建议进行以下更改。 使用固定大小的缓冲区(Say 20K),然后循环读取/写入。

对于循环做类似的事情

 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:你的程序并不总是按原样运行,因为read并不总是填满你给它的整个数组。