我有一个要写入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);
}
}
作为性能方面的极品,您可以使用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());