作为小白,之前自己写的模板文件导出太累赘了,记录一下从同事那里学到的打开世界大门的新操作。
public void exportFile(HttpServletResponse response) throws Exception {
//返回自定义的工作簿流,可以设置输出格式、输出内容等
Workbook book = exportService.export();
try (ServletOutputStream outputStream = response.getOutputStream()) {
String fileName = URLEncoder.encode("testFile.xlsx", "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
book.write(outputStream);
//outputStream流在close之前都会进行一次flush的,这里写不写无所谓
outputStream.flush();
}
}
本来只是记录一下语法糖的格式写文件导出,可以省去很多try-catch的代码行,无意中又有了一个新的发现——关于workbook对象的问题。
一直以来对流的关闭只是局限在inputstream和outputstream上,并没有考虑过其他对象是否需要关闭的问题。写这个笔记的时候,突然有个思考,workbook是什么对象,流吗?然后有了下面的事情经过。
发现一:Workbook对象具有close方法
Workbook book = null;
book.close();
那么这一步可以确定workbook对象,有close的对象肯定是需要关闭的
(不清楚是否有同名的方法,但是开源的代码应该不会有人写出close方法,但内部执行却不是处理流关闭的)
发现二:查看workbook对象的write具体实现方式时发现,没有直接表明workbook对象的关闭迹象,或可能在fs.close具体实现过程中对workbook进行了close操作,但这个因为目前能力不足所以还不清楚底层是怎么回事。
所以根据这两个发现,私以为这个workbook很可能是没有关闭的。联想到以前工作上的发生的一件事,线上在进行文件读写的时候很卡,然后查出来缓存占用率很高,但不知道是怎么回事,当时只能线上去清掉缓存。后来在查询问题的时候,找了很多关于流关闭的东西,但是那些问题没有可以让人信服的依据可以证明是他们导致的缓存占用率高。今天的这个发现,以后在写类似功能的时候就需要注意workbook对象的关闭了,虽然底层很可能是给他关掉的,稳妥起见自己再写一遍。