2016-10-07 2 views
1

В настоящее время я пишу тип сервлетов dropbox и нахожусь на том этапе, что я могу предоставить загружаемые файлы, и мне было интересно, что, если есть разница в эффективности между этими двумя способами.Servlet - что более эффективно при предоставлении загружаемого файла?

Это метод я использую в настоящее время, чтобы обеспечить загрузку, я использую FileInputStream писать файл, который становится загружаемым:

  PrintWriter out = response.getWriter(); 
      response.setContentType("APPLICATION/OCTET-STREAM"); 
      response.setHeader("Content-Disposition","attachment; filename=\"" + "/" + fileName + "\""); 
      FileInputStream fileInputStream = new FileInputStream(filePath[1]); 
      int i; 
      while ((i=fileInputStream.read()) != -1) 
      { 
       out.write(i); 
      } 
      fileInputStream.close(); 
      out.close(); 

Но после выполнения некоторых исследований я обнаружил, что большинство людей использует byte рода подход вместо:

OutputStream out = response.getOutputStream(); 
FileInputStream in = new FileInputStream(my_file); 
byte[] buffer = new byte[4096]; 
int length; 
while ((length = in.read(buffer)) > 0){ 
    out.write(buffer, 0, length); 
} 
in.close(); 
out.flush(); 

Является ли мой подход уступает каким-либо образом? или это выше метод просто более популярным, потому что это меньше кода?

ответ

2

PrintWriter оптимизирован для работы с CharSequence:

Печать отформатирован представления объектов к текстовому потоку вывода.

Аннотация класс для написания потоков символов. (От Writer документации)

В вас код, считываемый из файла побайтно и скопировать этот байт на PrintWriter. Лучше читать строки за строкой и написать полную строку на PrintWriter.


Использование Непосредственно OutputStream читать и писать кусок 4096 байт. Это более эффективно с точки зрения процессора, потому что вы делаете меньше while.

В любом случае разница очень ограничена, поскольку здесь скорость не связана с процессором, а со скоростью сети. Если вы попытаетесь проверить скорость обоих методов, вы увидите, что нет заметной разницы и на них может сильно повлиять сетевой трафик.

Кроме того, PrintWriter следует использовать только с текстовыми файлами, вместо этого решение OutputStream не зависит от типа файла.

-1

Вы можете использовать org.apache.commons.io.IOUtils для этой задачи

 try { 
      // getting output and input streams 
      // Setting response headers.     
       out.write(IOUtils.toByteArray(inputStream)); 
       out.flush(); 
     } catch(Exception e) {//or you can handle the appropriate Exception. 
     } finally { 
       IOUtils.closeQuietly(inputStream); 
     } 
+0

Что делать, если вы пытаетесь отправить файл 10GB? Насколько хорошо это будет работать с 64MB JVM? – stdunbar

+0

@stdunbar Это бросит OOM. Мой код - всего лишь пример лучшего способа копирования потока в ответ. Если это 10 ГБ файл, вы получите OOM в любом случае, если используете 64MB JVM, если вы не отправите файл в куски. Я предпочел бы другой способ, например, облачные хранилища и службы обмена файлами, которые упрощают отправку больших файлов, чем когда-либо, и часто намного быстрее и надежнее. – user3325637

Смежные вопросы