Самый эффективный способ записи файла в ServletOutputStream

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

Каков наиболее эффективный способ записи файла в javax.servlet.ServletOutputStream?

EDIT:

не будет ли это более эффективным, если бы использовался NIO?

Ответы

Ответ 2

У вас есть ServletOutputStream. Единственный способ, которым вы можете написать это, - через java.io. *. Вы не можете использовать NIO на нем вообще (кроме как через обертку с Channels, что бессмысленно: это все еще OutputStream внизу, и вы просто добавляете обработку сверху). Фактический ввод-вывод привязан к сети, и ваши записи все равно буферизуются контейнером сервлета (чтобы он мог устанавливать заголовок Content-Length), поэтому поиск настроек производительности здесь бессмысленен.

Ответ 3

Прежде всего, это не связано с сервлетами. Это относится к Java IO в целом. В конце концов, вы просто InputStream и OutputStream.

Что касается ответа, вы не единственный, кто задавался этим вопросом. На interwebs вы можете найти других, которые задавались вопросом о том же, но приложили все усилия, чтобы проверить/сравнить его сами:

В общем случае FileChannel с 256-байтовым массивом, который считывается через завернутый 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();
}

Ответ 4

Если вы не хотите добавлять эту банку в свое приложение, вам необходимо скопировать ее вручную. Просто скопируйте реализацию метода отсюда: 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;
}

поместите эти 2 метода в один из ваших вспомогательных классов, и вам хорошо идти.