文章目录
最近项目中有一个下载文件的功能,然后前端让后端接口返回文件流数据:
1、直接返回文件流:
首先使用FileInputStream
读取文件内容,然后设置HTTP响应头信息,包括文件类型和下载时的文件名。最后使用IOUtils.copy()
将文件内容写入到HTTP响应流中,实现返回文件流的功能。
public void download(String fileName, HttpServletResponse resp) {
String path = new File("").getAbsolutePath();
String filePath = path + "/" + fileName;
File file = new File(filePath);
try (FileInputStream fis = new FileInputStream(filePath)){
resp.setHeader("Content-Type", "application/octet-stream");
resp.setHeader("Content-Disposition", "attachment;filename=" +file.getName());
IOUtil.copy(fis, resp.getOutputStream());
resp.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
代码解析
FileInputStream
FileInputStream
是Java IO流中用于读取文件的一个类。它继承自InputStream
,可以读取一个文件的字节流,并将其传递给Java程序。在本示例中,我们使用FileInputStream
读取文件的字节流。
HttpServletResponse
HttpServletResponse
是Java Web应用中用于响应HTTP请求的一个类。它继承自ServletResponse
,包含了响应HTTP请求的常用方法,比如设置响应头信息、获取输出流等。在本示例中,我们使用HttpServletResponse
将文件内容写入到HTTP响应流中。
IOUtils
IOUtils
是Apache Commons IO中提供的一个类,用于在Java IO操作中提供更方便的常用方法。在本示例中,我们使用IOUtils.copy()
将FileInputStream
中的文件内容复制到HttpServletResponse
的输出流中,实现返回文件流的功能。
try-with-resources
try-with-resources 语句来确保资源(比如流或者连接)在使用完毕后被正确关闭。try-with-resources 语句可以自动关闭资源,而不需要显式使用 finally 块来进行关闭操作。
2、转成压缩包再返回文件流:
当下载文件比较大时,下载会很耗时,此时可以先把文件转成压缩包保存到本地,然后再转成文件流返回;
public void download(String fileName, HttpServletResponse resp) {
String path = new File("").getAbsolutePath();
String filePath = path + "/" + fileName;
String zipFilePath = path + "/" + fileName + ".zip";
// 转成压缩包
this.convertFileToZip(filePath, zipFilePath);
File file = new File(zipFilePath);
try (FileInputStream fis = new FileInputStream(zipFilePath)){
resp.setHeader("Content-Type", "application/octet-stream");
resp.setHeader("Content-Disposition", "attachment;filename=" +file.getName());
IOUtil.copy(fis, resp.getOutputStream());
resp.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
public void convertFileToZip(String filePath, String zipFilePath) {
File file = new File(filePath);
try (FileOutputStream fos = new FileOutputStream(filePath);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(file)) {
zos.putNextEntry(new ZipEntry(file.getName()));
byte[] buffer = new byte[1024];
int byteRead;
while ((byteRead = fis.read(buffer)) != -1) {
zos.write(buffer, 0 , byteRead);
}
zos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
}