有没有更好的方法将文件的全部内容写入OutputStream?

Mad*_*doc 19 java io

当我想将文件的全部内容写入a时OutputStream,我通常会将缓冲区分配为a byte[],然后forread数据从文件循环到InputStream缓冲区并将缓冲区内容写入OutputStream,直到InputStream没有更多的字节可用.

这对我来说似乎很笨拙.有一个更好的方法吗?

另外,我总是不确定缓冲区大小.通常,我分配1024个字节,因为它感觉很好.有没有更好的方法来确定合理的缓冲区大小?

在我目前的情况下,我想将文件的全部内容复制到写入HTTP响应内容的输出流中.因此,这不是关于如何在文件系统上复制文件的问题.

mat*_*sev 28

对于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
}
Run Code Online (Sandbox Code Playgroud)

注意,既然你正在处理HttpServletResponseis也是一个好主意,设置正确的响应头.将实际文件数据复制到响应之前,请添加以下行:

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);
Run Code Online (Sandbox Code Playgroud)

请注意,传递给内容处置的文件名的编码很重要,请参阅此问题.


mha*_*ler 23

Apache Commons-IO:

IOUtils.copy(fileInputStream,outputStream);
Run Code Online (Sandbox Code Playgroud)

JDK NIO

new FileInputStream(file).getChannel().transferTo(otherChannel);
Run Code Online (Sandbox Code Playgroud)

  • 别忘了关闭`FileInputStream` (2认同)

Boz*_*zho 9

通过commons-io,您可以获得一个单行解决方案:

IOUtils.copy(yourFileInputStream, outputStream);
Run Code Online (Sandbox Code Playgroud)

请注意,您必须手动(或通过IOUtils.closeQuitely(..))关闭流