问题描述
在开发环境运行或debug皆可以成功获取在src/main/resource下的文件,但一旦打包为jar,则获取到的文件数据量为0.
结论先行
首先确保自己的代码的部署可行性,参考java(包括springboot)读取resources下文件方式
除此之外还要确认inputStream是否为null(不成功会有java.lang.NullPointerException),resource文件是否获取成功(不成功会有java.io.FileNotFoundException)
如果以上都没有问题,则有可能是我面临的情况:
网上绝大部分文章都采用了inputStream.available()
初始化字节数组大小,但实际上其值为0,其结果将导致inputstream写入失败。具体原因是因为源码接口直接返回0,详见Spring Boot项目以jar包形式启动,下载resources目录中文件为空的解决方案及原因分析。
//错误代码
@GetMapping("/equipment/batchAdd")
public void downloadAddEquipmentTemplate(HttpServletResponse response){
response.setContentType("application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode("设备导入模板", "UTF-8") + ".xlsx");
response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
try {
Resource resource = new ClassPathResource("docs/设备导入模板.xlsx"); //静态文件位置
InputStream inputStream = resource.getInputStream();
byte[] buffer = new byte[inputStream.available()]; //问题所在
inputStream.read(buffer);
inputStream.close();
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
outputStream.write(buffer);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
response.setStatus(404);
}
}
解决方法
使用Resource类自带获取资源大小的方法初始化数组,其他不变
int fileSize = new Long(resource.contentLength()).intValue();//文件在2GB以下可行
byte[] buffer = new byte[fileSize];
我试过的方法
- 假如你的项目在/target/classes目录下已能看到你想获取的文件,则下面的方法不用尝试
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>mappers/*.*</include>
<include>application.properties</include>
<include>logback-spring.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xlsx</include>
</includes>
</resource>
</resources>
</build>
- 如果上述第二步检验没有问题,则文件是获取成功的,不需要修改获取Resource的方式