java下载文件无响应,Java文件下载的几点总结-当我们谈下载时要注意什么

写在前面

当我们谈下载时,要注意什么?IO?API?SDK?

一、基本知识

下载的过程就是 复制的过程,三个基本名词 Source File,Target File,传输工具

二、Source File

源文件,Java中常见3种源文件,

资源路径-Classpath

文件系统 - File System

磁盘目录

2.1、资源路径

常见场景很多,包括各种模板、手册(Word,Excel,PDF…),相关静态文件…

这里一般通过两个对象即可操作资源文件,可参考这里,

获取 输出、输入流,即可完成下载

2.2、文件系统

这里的场景是基于一个文件服务,目前很多的文件服务的选择

fastDfs、HDFS、GlusterFS、各种云盘、各种云的OSS对象存储、甚至某个超链接…等等都可定义为文件系统的存储方式

文件系统的文件操作方法是基于 API,或者 超链接方式,即可

这里有可用的 SDK 或者 相关工具类封装…完成下载

类似如下,apache common

public static void downloadWithApacheCommons(String url, String localFilename) {

int CONNECT_TIMEOUT = 10000;

int READ_TIMEOUT = 10000;

try {

FileUtils.copyURLToFile(new URL(url), new File(localFilename), CONNECT_TIMEOUT, READ_TIMEOUT);

} catch (IOException e) {

e.printStackTrace();

}

}

2.3、磁盘目录

这里需要注意,开发环境,测试环境。以及生产环境因系统不同,文件分割符会有所不同

is = new FileInputStream(filePath + "\\" + path.getFileName()); // windows

is = new FileInputStream(filePath + "/" + path.getFileName()); // linux 目录分隔符

JDK 中 File.separator 可自动识别系统分隔符,因此上述可替换为

is = new FileInputStream(filePath + File.separator + path.getFileName());

还要注意 ,Java 项目 和 Springboot 项目测试中的差别,即springboot 项目中的 所获取Path路径是相对路径,会把磁盘某文件真实路径,映射 当前项目下,导致无法获取真实文件路径,获取输入流失败,可参考上述,拼接文件的完整路径,获取输入流

三、Target File

这里是指期望下载文件到某位置,一般通过浏览器方式下载(通过输出流写到浏览器默认下载目录)

四、传输工具

这里是指 IO 流的 读写方式,包括 字符流、字节流

示例(指向磁盘目录下载)

这里完成了 指向目标目录,过滤文件,下载

// 接口定义

@GetMapping("/manual")

public void manualDownload(HttpServletResponse response) {

InputStream is = null;

ServletOutputStream os = null;

String filePath = configService.findDefaultFilePath();

if (filePath == null) {

throw new CustomeException("文件地址为空");

}

List results = new LinkedList();

try {

Files.walkFileTree(Paths.get(filePath), new FindJavaVisitor(results));

if (results.size() != 1) {

throw new CustomeException("文件异常" + results.size());

}

Path path = results.get(0);

is = new FileInputStream(filePath + File.separator + path.getFileName());

response.addHeader("charset", "utf-8");

String encodeName = URLEncoder.encode(path.getFileName().toString(), StandardCharsets.UTF_8.toString());

response.setHeader("Content-Disposition", "attachment; filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);

// copy (输入流,输出流)

os = response.getOutputStream();

IOUtils.copy(is, os);

response.flushBuffer();

} catch (Exception e) {

throw new CustomeException("文件异常");

} finally {

try {

if (os != null) {

os.close();

}

if (is != null) {

is.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

// 文件过滤

private static class FindJavaVisitor extends SimpleFileVisitor {

private List result;

public FindJavaVisitor(List result) {

this.result = result;

}

@Override

public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {

if (file.toString().endsWith(".docx")) {

result.add(file.getFileName());

}

return FileVisitResult.CONTINUE;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值