Наиболее эффективный способ записи файла в ServletOutputStream - PullRequest
15 голосов
/ 10 января 2011
ServletOutputStream output = response.getOutputStream();
output.write(byte[]);

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

РЕДАКТИРОВАТЬ:

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

Ответы [ 4 ]

34 голосов
/ 10 января 2011
IOUtils.copy(in, out);
out.flush();
//...........
out.close(); // depends on your application

Где in - это FileInputStream , а out - это SocketOutputStream. IOUtils - это утилита из модуля IO Commons в Apache Commons .

4 голосов
/ 11 января 2011

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

3 голосов
/ 10 января 2011

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

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

Как правило, самый быстрый способ - 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();
}
0 голосов
/ 10 января 2011

Если вы не хотите добавлять этот 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;
}

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

...