Подтвердить что ты не робот

Есть ли лучший способ написать полное содержимое файла в OutputStream?

Когда я хочу написать полное содержимое файла в OutputStream, я обычно выделяю буфер как byte[], а затем создаю цикл for для read данных из файла InputStream в буфера и записать содержимое буфера в OutputStream, пока InputStream не будет иметь больше байтов.

Это кажется довольно неуклюжим для меня. Есть ли лучший способ сделать это?

Кроме того, я всегда не уверен в размере буфера. Обычно я выделяю 1024 байта, потому что он просто чувствует себя хорошо. Есть ли лучший способ определить разумный размер буфера?

В моем текущем случае я хочу скопировать полное содержимое файла в выходной поток, который записывает содержимое ответа HTTP. Итак, это не вопрос о том, как копировать файлы в файловой системе.

4b9b3361

Ответ 1

Для Java 1.7+ вы можете использовать Files.copy(Path, OutputStream), например

HttpServletResponse response = // ...
File toBeCopied = // ...

try (OutputStream out = response.getOutputStream()) {
    Path path = toBeCopied.toPath();
    Files.copy(path, out);
    out.flush();
} catch (IOException e) {
    // handle exception
}

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

String mimeType = URLConnection.guessContentTypeFromName(toBeCopied.getName());
String contentDisposition = String.format("attachment; filename=%s", toBeCopied.getName());
int fileSize = Long.valueOf(toBeCopied.length()).intValue();

response.setContentType(mimeType);
response.setHeader("Content-Disposition", contentDisposition);
response.setContentLength(fileSize);

Обратите внимание: важна кодировка имени файла, переданного в распоряжение содержимого, см. этот вопрос.

Ответ 2

Apache Commons-IO:

IOUtils.copy(fileInputStream,outputStream);

JDK NIO

new FileInputStream(file).getChannel().transferTo(otherChannel);

Ответ 3

С commons-io у вас есть однострочное решение:

IOUtils.copy(yourFileInputStream, outputStream);

Обратите внимание, что вам придется закрыть свои потоки вручную (или IOUtils.closeQuitely(..))