java从InputStream读取到OutputStream的最快方式
下面的代码以1.3秒的速度传输2.43 MB文件
byte[] buff = new byte[64*1024];
private static void flow(InputStream is, OutputStream os, byte[] buf )
throws IOException {
int numRead;
while ( (numRead = is.read(buf) ) >= 0) {
os.write(buf, 0, numRead);
}
}
将InputStream
流式传输到OutputStream
的最快方式是什么
更新:
数据源是一个缓存,具体来说是EHCache:
byte[] cached = cacheService.get(cacheKey); // Just `2 ms` to get the bytes, very fast
if(cached != null && cached.length > 0) {
flow(ByteSource.wrap(cached).openStream(), outputStream, buff);
}
# 1 楼答案
我不能断言它是最快的,但我建议使用
apache-commons-io
的IOUtils
。特别是并尝试使用不同的
bufferSize
值进行基准测试https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/IOUtils.html#copy(java.io.InputStream,%20java.io.OutputStream,%20int)
这里真正的问题是您正在处理的高级别抽象。如果您确切地知道数据来自何处(例如文件系统)及其去向(例如网络套接字),并且您知道正在使用哪个操作系统,那么就可以利用内核的流支持来加快速度
在谷歌上搜索“零拷贝内核io”,我发现了这篇文章,它是一个不错的概述: https://xunnanxu.github.io/2016/09/10/It-s-all-about-buffers-zero-copy-mmap-and-Java-NIO/
# 2 楼答案
由于Java 9,InputStream提供了一个transferTo(OutStream)方法,也可以使用Java 7 Files。 同样,也没有关于哪一个是最快的,但你也可以对它们进行基准测试
参考资料:
# 3 楼答案
我也会说commons io:IOUtils::copy这可能比简单的方法做得更好,但代码似乎与您的代码做得一样(请参见copyLarge),但关于Java 9的答案使它成为一个更好的选择
然而,您的问题可能不是如何复制,而是缺少缓冲:您可以尝试在现有流的基础上使用
BufferedInputStream
和BufferedOutputStream
:Files.newInputStream
未被缓冲李>Files.newOutputStream
未被缓冲李>FileChannel
和ByteBuffer
李>您应该进行JMH基准测试:
虽然执行可能需要时间,但通往最快的的道路意味着测量