服务提供者
@ApiOperation("下载文件")
@GetMapping("/download")
public void download(HttpServletRequest request, HttpServletResponse response, @RequestParam("path")String path) throws IOException {
request.setCharacterEncoding("utf-8");
File file = new File(path);
String fileName = file.getName();
ServletOutputStream outputStream = response.getOutputStream();
response.setContentType("application/octet-stream");
fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
byte[] buffer = new byte[1024];
int readLength;
FileInputStream fis = new FileInputStream(file);
while ((readLength=fis.read(buffer))!= -1) {
outputStream.write(buffer, 0, readLength);
outputStream.flush();
}
IoUtil.close(fis);
IoUtil.close(outputStream);
}
服务消费者
feign接口,必须返回Response
@GetMapping("/download")
Response downloadFile( @RequestParam("path")String path) throws IOException;
controller
@ApiOperation(value = "下载文件")
@GetMapping("/downloadFile")
public void downloadFile(HttpServletResponse response, @RequestParam("path")String path) throws IOException {
Response responseFromRemote = proxyFileFeign.downloadFile(path);
HttpUtil.downloadFeignFile(response, responseFromRemote);
}
工具类实现
/**
* feign代理下载文件工具
* @param responseFromRemote feign的response
* @date 2022/4/22
*/
public static void downloadFeignFile(HttpServletResponse response, Response responseFromRemote) throws IOException {
Response.Body body = responseFromRemote.body();
/**FilterInputStream**/
InputStream inputStream = body.asInputStream();
OutputStream outputStream = response.getOutputStream();
response.setHeader("content-disposition",responseFromRemote.headers().get("content-disposition").stream().collect(Collectors.joining(";")));
response.setHeader("content-type",responseFromRemote.headers().get("content-disposition").stream().collect(Collectors.joining(";")));
byte[] buffer = new byte[1024 * 8];
int count;
while ((count = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
outputStream.flush();
}
IoUtil.close(inputStream);
IoUtil.close(outputStream);
}
读写文件需要注意的点
1.文件大小未知的情况,不要一次性读取整个文件进内存,太耗内存,甚至oom
2.小文件如果一次性读取,inputStream.available()的返回值不是全部字节大小,根据jdk注释
Returns:
an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking or 0 when it reaches the end of the input stream.
返回的是预估可以一次性不阻塞读取的大小。
本文由 转啊转 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/09/25 10:20