我有一个想要写入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);
我想知道在速度和效率方面可能是最好的方法。
答案 0 :(得分:45)
只需要用块写入,而不是先将它完全复制到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());
答案 1 :(得分:1)
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);
}
答案 2 :(得分:0)
我认为这与最好的方式非常接近,但我建议进行以下更改。使用固定大小的缓冲区(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并不总是填满你给它的整个数组。