最近发现了一个很好用的文件上传和下载的方式,那么今天就带给大家,希望能够帮到大家。
首先项目是基于SpringBoot开发,如果使用Spring也不影响
功能演示:
废话不多说直接上代码
- 1.创建一个StoreService用于实现文件上传和下载
@Service
@Slf4j
public class StoreService {
//用于获取配置文件中的属性的类
@Autowired
private Environment env;
//文件保存路径
private String fileStorePath;
//用于锁
private final Object createFileLock = new Object();
/**
* 保存文件 返回file key
*/
public String upload(MultipartFile file) {
return storeFile(file);
}
public void download(String key, HttpServletResponse response) {
Assert.hasText(key, "Invalid key");
try {
Files.copy(getFile(key), response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
throw new IllegalArgumentException("下载发送错误");
} catch (StringIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Invalid key!");
}
}
@PostConstruct
private void setFileStorePath() {
String property = env.getProperty("file.store.path");
Assert.notNull(property, "must set fileStorePath");
log.info("path: {}", property);
fileStorePath = property;
}
private boolean checkPathConflict(Path path) {
return Files.exists(path);
}
//创建图片的保存路径
private Path name2Path(String fileName) {
//16 * 16 * (16*16)
return Paths.get(fileStorePath, fileName.substring(0, 2), fileName.substring(2, 4), fileName);
}
//保存文件实现
private String storeFile(MultipartFile file) {
synchronized (createFileLock) {
//文件保存路径
Path path;
//图片名称
String fileName;
do {
//图片名称赋值
fileName = UUID.randomUUID().toString();
//保存路径赋值
path = name2Path(fileName);
//循环条件就是 如果文件地址不存在的情况下
} while (checkPathConflict(path));
try {
//创建文件夹
Files.createDirectories(path.getParent());
//复制文件到指定文件夹下面
Files.copy(file.getInputStream(), path);
return fileName;
} catch (IOException e) {
log.info("io err", e);
throw new IllegalArgumentException("文件上传失败");
}
}
}
//现在图片实现
private Path getFile(String fileName) {
//获取文件保存路径
Path path = name2Path(fileName);
Assert.isTrue(Files.exists(path), "Invalid Filename " + fileName);
return path;
}
}
- 2.创建一个Controller用于提供访问
@Slf4j
@RestController
public class FileController {
@Autowired
StoreService storeService;
@PostMapping(value = "/file/upload")
public Object upload(MultipartFile multipartFile){
return storeService.upload(multipartFile);
}
@PostMapping(value = "/file/download")
public Object download(String key, HttpServletResponse response){
storeService.download(key,response);
return key+"图片返回成功";
}
}
3.在配置文件加入文件保存地址的相关配置
file.store.path=E:\\projectFiles\\market
到了这里我的E:\projectFiles\market文件夹下面几多了一串文件夹和一个文件,当我们在调用download接口的时候只需要输入我们在上传的时候返回的一串字符串就可以文成图片的下载了,至于返回格式需要自己设置一下,我这里是在其他地方设置了统一返回格式的
~~到了这里就结束了,谢谢大家的观看