将文件写入ServletOutputStream的最有效方法

问题描述 投票:0回答:5
ServletOutputStream output = response.getOutputStream();
output.write(byte[]);

将文件写入 javax.servlet.ServletOutputStream 最有效的方法是什么?

编辑:

如果使用NIO不是更有效吗?

java performance file servlets nio
5个回答
38
投票
IOUtils.copy(in, out);
out.flush();
//...........
out.close(); // depends on your application

其中

in
FileInputStream
out
SocketOutputStream
IOUtils 是来自 Apache Commons 中的 Commons IO 模块的实用程序。


6
投票

您有一个 ServletOutputStream。您可以写入的唯一方法是通过 java.io.*。你根本不能在它上面使用 NIO(除了用

Channels
包装之外,这是毫无意义的:它仍然是下面的
OutputStream
,你只是在顶部添加处理)。实际的 I/O 是网络绑定的,并且您的写入无论如何都会被 servlet 容器缓冲(以便它可以设置 Content-Length)标头,因此在这里寻找性能调整是没有意义的。


3
投票

首先,这与servlet无关。这通常适用于 Java IO。毕竟你只有一个

InputStream
和一个
OutputStream

至于答案,您并不是唯一一个对此感到好奇的人。在互联网上,您可以找到其他人也有同样的疑问,但自己努力测试/基准测试:

一般来说,具有 256K 字节数组的

FileChannel
,通过包装的
ByteBuffer
读取并直接从字节数组写入是最快的方法。确实,蔚来。

FileInputStream input = new FileInputStream("/path/to/file.ext");
FileChannel channel = input.getChannel();
byte[] buffer = new byte[256 * 1024];
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);

try {
    for (int length = 0; (length = channel.read(byteBuffer)) != -1;) {
        System.out.write(buffer, 0, length);
        byteBuffer.clear();
    }
} finally {
    input.close();
}

0
投票

我相信,如果您使用 Java 9 及更高版本,您可以直接使用

InputStream.transferTo
方法:

inputStream.transferTo(outputStream);

看起来干净又方便。但该方法在 Java 8 (1.8) 中不可用。


-1
投票

如果您不想将该 jar 添加到您的应用程序中,那么您必须手动复制它。只需从这里复制方法实现:http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java?revision=1004358&view =标记

private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

public static int copy(InputStream input, OutputStream output) throws IOException {
  long count = copyLarge(input, output);
  if (count > Integer.MAX_VALUE) {
    return -1;
  }
  return (int) count;
}

public static long copyLarge(InputStream input, OutputStream output)
    throws IOException {
   byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
   long count = 0;
   int n = 0;
   while (-1 != (n = input.read(buffer))) {
     output.write(buffer, 0, n);
     count += n;
   }
   return count;
}

将这 2 个方法放入您的辅助类之一中,然后就可以开始了。

© www.soinside.com 2019 - 2024. All rights reserved.