将File写入ServletOutputStream的最有效方法

时间:2011-01-10 09:48:24

标签: java performance file servlets nio

ServletOutputStream output = response.getOutputStream();
output.write(byte[]);

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

修改

如果使用NIO,

会不会更有效?

4 个答案:

答案 0 :(得分:33)

IOUtils.copy(in, out);
out.flush();
//...........
out.close(); // depends on your application

其中inFileInputStreamoutSocketOutputStreamIOUtilsCommons IOApache Commons模块中的实用程序。

答案 1 :(得分:4)

你有一个ServletOutputStream。你可以写的唯一方法是通过java.io. *。根本不能在它上面使用NIO(除了通过Channels包裹,这是没有意义的:它下面仍然是OutputStream,你只是在顶部添加处理)。实际的I / O是网络绑定的,无论如何,servlet容器都会缓冲你的写入(这样它可以设置Content-Length)头,所以在这里寻找性能调整是毫无意义的。

答案 2 :(得分:3)

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

至于答案,你并不是唯一一个对此感到疑惑的人。在互联网上,您可以找到其他人,他们对此感到疑惑,但却努力自己测试/基准测试:

通常,具有256K字节数组的FileChannel是通过包装ByteBuffer读取并直接从字节数组写入的,这是最快的方法。的确,NIO。

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();
}

答案 3 :(得分:-1)

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

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;
}

将这两个方法放在你的一个帮助程序类中,你就可以了。