我有一个输入流,我想将其写入HttpServletResponse。有一种方法,由于使用字节[],需要花费的时间太长
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);
我想知道在速度和效率方面,什么可能是最好的方法。
我认为这是非常接近最佳的方式,但我建议进行以下更改。使用固定大小的缓冲区(比如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并不总是填满你给它的整个数组。
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);
}
只需在块中写入,而不是首先将其完全复制到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通道和直接分配的ByteBuffer。在一些自定义实用程序类中创建以下实用程序/助手方法,例如:
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());
Kafka流中是否内置了允许将单个输入流动态连接到多个输出流的功能?允许基于true/false谓词进行分支,但这不是我想要的。我希望每个传入日志都确定它将在运行时流到的主题,例如,日志将流到主题和日志将流到主题。 我可以在流中调用,然后写给Kafka制作人,但这似乎不是很好。在Streams框架中是否有更好的方法来实现这一点?
问题内容: 目标是: 创建文件读取流。 用管道将其压缩到gzip() 然后将zlib输出的读取流通过管道传输到: 1)HTTP 对象 2) 和 可写文件流,以保存压缩后的输出。 现在我可以降到3.1了: …效果很好,但是我还需要 将压缩后的数据保存到文件中, 这样我就不需要每次都进行zip压缩,并且能够直接将压缩后的数据作为响应流化。 那么,如何在Node中一次将一个可读流传送到两个可写流中? 将
问题内容: 我一直在进行一些性能分析和基准测试,以优化向临时文件的写操作,以捕获来自的任何错误。 具体来说,我们正在写入缓冲区,检查是否有错误,如果没有,则写出到。但是,问题在于临时缓冲区的请求开销有些明显: 启用剖析时约为6.2k req / s-27.6k-> 21.4k,禁用时为29k-> 24k; 每个请求的延迟增加9毫秒(40毫秒-> 49毫秒)。 当然,21k req / s仍然是很多
我正在调用一个客户端的下载服务,该服务发送回MIME数据,并试图保存一个zip文件。 该服务不仅返回文件本身,还返回其他几个MIME字段。所以当我使用entity.getContent()打开输入流时,我最终会将所有这些数据写入我的zip文件,而我只希望写入一部分“有效载荷”。我已经搜索过了,无论如何都看不到,只从内容中获得一个单独的部分。 代码如下: 生成的文件的内容如下所示。请注意,我只希望将
如何在单个作业中使用Spark根据密钥写入多个输出。 相关:按键写入多个输出扩展Hadoop,一个MapRe员作业 例如。 将确保为 而将是 编辑:我最近添加了一个新的答案,包括完整的导入,皮条客和压缩编解码器,请参阅https://stackoverflow.com/a/46118044/1586965,这可能是有帮助的,除了早期的答案。
您好,我正在学习服务器-客户端应用程序的示例,我不明白客户端如何从服务器接收字符串。 服务器运行执行以下操作的线程: 在客户端类中有以下代码: 和和在线程和客户端类中以相同的方式实现,包括: 其中,也是同一个对象,它是客户机的socket 我的问题是为什么字符串正是字符串?服务器在输出流中写入,客户端从输入流中拾取,这不是两个不同的内存区域吗?