需求是这样的,要求通过阿里云的路径获取文件,并打包成压缩包,提供下载,在网上找了好久都没有相关的资料,正好在机缘巧合下成功的获取到了文件,并成功打包
这个方法需要提供两个入参:
fileUrl:外网的路径 directory:临时文件夹
有需要的小伙伴可以参考一下
这两个参数一个是外网的路径,一个是临时文件夹,获取到的文件,获取都的文件会录入到临时文件夹中
/**
* 读取文件到临时目录
* @param fileUrl
* @param directory
* @throws IOException
*/
private static void downloadFile(String fileUrl, String directory) throws IOException {
URL url = new URL(fileUrl);
try (InputStream in = url.openStream();
OutputStream out = new FileOutputStream(directory + File.separator + getFileNameFromUrl(fileUrl))) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
}
private static String getFileNameFromUrl(String fileUrl) {
return fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
}
这里是另一部分代码,可以放在单独的代码块中,可以看到我在循环中调用了上边的方法获取多个文件,存到临时文件夹中,因为在我的需求中有三个文件格式所以需要编历
String tmpDirPath = FileUtil.getTmpDirPath();
File tempFolder = new File(tmpDirPath);
try {
// 创建临时文件夹
tempFolder.mkdirs();
// 根据发票id查询发票,将发票号作为压缩文件名
BizInvOut bizInvOut = this.queryEntity(param.getInvoiceId());
// 压缩文件的临时文件路径
String zipFilePath = tmpDirPath + File.separator + bizInvOut.getInvoiceNumber()+".zip";
// 创建 ZipOutputStream
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
byte[] buffer = new byte[1024];
for (BizInvFile bizInvFile : bizInvFiles) {
DevFile devFile = devFileService.getById(bizInvFile.getFileId());
try {
downloadFile(devFile.getDownloadPath(), tmpDirPath);
File tempFile = new File(tmpDirPath + File.separator + devFile.getObjName());
// 将下载的文件添加到压缩文件中
ZipEntry zipEntry = new ZipEntry(tempFile.getName());
zipOutputStream.putNextEntry(zipEntry);
try (FileInputStream fileInputStream = new FileInputStream(tempFile)) {
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, length);
}
}
// 关闭当前 entry
zipOutputStream.closeEntry();
// 删除临时文件
tempFile.delete();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
// 下载压缩文件
File zipFile = new File(zipFilePath);
CommonDownloadUtil.download(zipFile, response);
// 删除临时文件夹
FileUtil.del(tempFolder);
} catch (IOException e) {
throw new RuntimeException(e);
}
在上述代码中我调用的是以下载的方法
这段代码是用于在 Java Servlet 环境中实现文件下载功能
-
设置响应头部,指示浏览器以附件形式下载文件。
URLUtil.encode(fileName)
是对文件名进行编码,避免文件名中包含特殊字符导致下载问题。 -
添加响应头部,指示下载文件的字节长度,有助于浏览器正确处理下载文件的进度显示。
-
设置响应头部,允许跨域请求。
-
设置响应头部,指示允许浏览器访问的响应头。
-
设置响应的 MIME 类型为
application/octet-stream
,表示以二进制流形式下载文件,charset=UTF-8
指定了字符编码。 -
将文件内容写入响应的输出流,实现文件下载功能。这里假设
fileBytes
是文件的字节数组,IoUtil.write
是用于将字节数组写入输出流的工具方法。参数true
表示在写入完成后关闭输出流。
/**
* 下载文件
*
* @param file 要下载的文件
* @param response 响应
* @date 2020/8/5 21:46
*/
public static void download(File file, HttpServletResponse response) {
download(file.getName(), FileUtil.readBytes(file), response);
}
public static void download(String fileName, byte[] fileBytes, HttpServletResponse response) {
try {
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode(fileName));
response.addHeader("Content-Length", "" + fileBytes.length);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("application/octet-stream;charset=UTF-8");
IoUtil.write(response.getOutputStream(), true, fileBytes);
} catch (IOException e) {
log.error(">>> 文件下载异常:", e);
}
}