序言
笔者最近在查看作业评阅零碎的时候,对于其中的附件上传和下载不太理解,通过写这篇文章来记录本人的播种。
文件传到哪里
1. 传到工程目录下
在一些文件存储量很小的工程中,有一些上传文件搁置在工程自身的目录下,然而随着文件上传的量越来越大,工程自身所在的文件夹容量会越来越大,不仅打包和部署的效率会升高,工程的启动和运行也会变慢,所以个别不会采纳这做法。
2. 上传到工程所在服务器
将文件专门上传到 Web 利用工程所在容器(如Tomcat
)位于的服务器中,独自开拓一个盘符或文件夹用于存储上传的图片,这种做法让上传 文件与工程自身拆散,工程的打包和启动效率不受到任何影响。然而如果当前呈现了海量图片,Web 利用工程所在的服务器的效率会升高,这样也会间接地升高利用的执行效率,所以在上传图片量不大的状况下,能够采纳该做法。
3. 搭建文件服务器
个别大型的互联网我的项目,都会为本人的文件上传独自架设一个文件服务器(有集群的利用,可能会有多台文件服务器),也有独立解决文件上传、文件拜访的服务器。这种计划就是太烧钱。
总结:下面剖析了三种计划的特点和优缺点。第一种个别不采取,第二种可能会采取,最罕用的就是第三种计划。笔者所用零碎是应用的第一种计划。
上传
MultipartFile 工具类
MultipartFile
是 SpringMVC
提供简化上传操作的工具类。
在不应用框架之前,都是应用原生的 HttpServletRequest
来接管上传的数据,文件是以二进制流传递到后端的,而后须要咱们本人转换为 File 类,十分麻烦。应用了 MultipartFile
工具类之后,咱们对文件上传的操作就简便许多了。
以下是 MultipartFile
工具类全副的接口办法:
办法名 | 返回值 | 作用 |
---|---|---|
getContentType() | String | 在取文件 MIME 类型 |
getlnputStream() | InputStream | 获取文件流 |
getName() | String | 获取 form 表单中文件组件的名字 |
getOriginalFilename() | String | 获取上传文件件的原名 |
getSize() | long | 获取文件的大小,单位为 byte |
isEmpty() | boolean | 是否为空 |
transferTo(File dest) | void | 将数据保留到一个指标文件中 |
实现上传外围代码:
public void saveFile(MultipartFile multipartFile, Path saveFilePath) throws Exception {logger.debug("获取文件名");
String fileName = multipartFile.getOriginalFilename();
logger.debug("从文件名中截取拓展名");
// 从 "." 最初一次呈现的地位的下一位开始截取,获取扩展名
assert fileName != null;
String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
logger.debug("设置保留文件名");
saveName = fileName;
logger.debug("判断上传的文件是否为空");
if (multipartFile.isEmpty()) {throw new RuntimeException("上传的附件不能为空" + fileName);
}
logger.debug("如果目录不存在,则创立目录。如果目录存在,则不创立");
if (!Files.exists(saveFilePath)) {Files.createDirectories(saveFilePath);
new File(saveFilePath.resolve("index.html").toString()).createNewFile();}
logger.debug("将文件挪动至贮存文件的门路下");
Files.copy(multipartFile.getInputStream(), saveFilePath.resolve(saveName),
StandardCopyOption.REPLACE_EXISTING);
}
笔者间接用文件名来将文件存储在工程中,这种行为是很不平安的,所以倡议用本人定义的加密解密方法来解决此问题,存入服务器的文件就会变成二进制文件,当他人间接冲服务器拿到文件时,也无奈查看,这就保障了安全性。
下载
下载局部外围代码
public void download(File f, OutputStream outputStream) {Path path = Paths.get(f.getPath())
.resolve(f.getName());
java.io.File file = path.toFile();
logger.debug("输入文件类型");
FileInputStream inputStream;
try {inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {logger.error("读取文件出错" + f.getId() + file.getAbsolutePath());
e.printStackTrace();
throw new RuntimeException("读取文件产生谬误");
}
try {org.apache.commons.io.IOUtils.copy(inputStream, outputStream);
} catch (IOException e) {logger.error("下发数据时产生了谬误");
e.printStackTrace();
throw new RuntimeException("下发数据时产生了谬误");
}
}