目录
整体逻辑思路:
第一步 : 发送请求
了解apipost/postman上传文件方式body -> multipart/form-data
apipost快速上手-> 链接
第二步: controller层 请求
第三步: 实现类 业务逻辑
第四步: [oss上传,是一个/链接,包含回调异常和封装的util包 ]
第五步: 上传oss成功 返回了url
第六步: 删除本地文件, 突遇问题
逻辑: 无论上传的成不成功 ,都删除本地文件 返回状态
6.1 -> 把升级版的删除 放到 ossutils 的return里面
看第七步----> 解决办法
第七步: 发现文件被占用问题 并解决
文件删除util包, 解决文件被占用问题
调用gc的几种方式
第8步: 补充: 想要删除文件夹
方法 是循环删除文件 后删除文件夹
文件->前端发送请求 -> 后端upload->本地文件 -> oss ->无论成不成功 删除本地 返回状态
难点: 删除本地文件的时候 明明显示文件路径存在却无法删除问题
Postman,ApiPost, Idea httpclient tools, 替代swagger,零侵入 接口文档生成 及几种后端测试方式
@RequestMapping(value = "/uploads", method = RequestMethod.POST)
@ResponseBody
public SystemResult uploads(MultipartFile[] file, HttpSession session) {
log.debug("===> 开启文件上传 <===");
return uploadService.fileUploadCtrl(file,session);
}
/**
* @Author pzy
* @Version 0.1.0
*/
@Service
@Slf4j
public class OSSAddServiceImpl implements OSSAddService {
// @Value("${file.uploadFolder}")
private static final String uploadPath = "D:/usr/local/src/images";//windows
//private static final String uploadPath = "/usr/local/src/images";//linux
@Override
public Result OSSAddImg(MultipartFile[] file, HttpSession session) {
//上传目录地址
String uploadDir = uploadPath;
log.debug(uploadPath);
//(最新修改)如果目录不存在,自动创建文件夹(修复)
if (!createFile(1, new File(uploadDir), false)) {
log.error("-------> 自动创建文件或文件夹失败!!! <--------");
}
String suffix = null;
String fileName = null;
// HashMap hashMap = new HashMap();
try {
//遍历文件数组执行上传(多文件上传需要)
for (int i = 0; i < file.length; i++) {
if (file[i] != null) {
log.debug("开始上传文件.......");
//调用上传方法
suffix = file[i].getOriginalFilename().substring(file[i].getOriginalFilename().lastIndexOf(".")); //后缀名
fileName = UUID.randomUUID() + suffix;
IOUtils.copy(file[i].getInputStream(), new FileOutputStream(uploadDir + "\\" + fileName));
//file[i].transferTo(new File(uploadDir+"\\"+fileName));
log.debug("上传" + uploadDir + "\\" + fileName + "文件成功!");
}
}
log.debug("上传结束!所有文件上传文件至:" + uploadDir);
System.out.printf("文件名->%s\n", fileName);
} catch (Exception e) {
//打印错误堆栈信息
e.printStackTrace();
log.error("上传文件失败,请检查后重试!!!");
// hashMap.put("uploadMessage", "上传失败");
return Result.fail(String.valueOf(500), "上传失败");
}
log.debug(fileName + ", " + (uploadPath + "\\" + fileName));
//上传oss 没有进一步封装
Result systemResult = OSSUtils.OSSUpload(fileName, uploadPath);
// String path = (uploadPath + "\\" + fileName);
// System.out.println(path);
return systemResult;
// return Result.success(200);
}
/**
* 判断文件是否存在,不存在就创建
*
* @param file
*/
public static boolean createFile(int type, File file, Boolean flag) {
if (type == 1) {
if (!file.exists()) {
return file.mkdirs();
}
}
//其他就是0 文件及目录创建(存在bug)
if (file.exists()) {
log.debug("文件及相关路径存在!!!");
} else {
log.info("文件不存在 ,创建文件以及文件夹 ...");
//getParentFile() 获取上级目录(包含文件名时无法直接创建目录的)
if (!file.getParentFile().exists()) {
log.info("文件及其路径不存在, 创建路径文件!!!");
//创建层级目录
if (!file.getParentFile().mkdirs()) {
return false;
}
}
if (flag) {
try {
//上层目录创建文件
log.info("文件夹创建开启,在上层目录下创建文件夹");
if (file.createNewFile()) {
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
}
如果是微服务可以在配置中心修改
内容必须与file.uploadFolder一致 防止空指针可以添加默认值 这里我没添加
注意到没有: [最近更新 回调存在的问题也包含在内]
SystemResult systemResult = OSSUtils.OSSUpload(fileName, uploadPath);
这个util包没有 自己封装的 嘿嘿
下面这篇文章中 完整的ossUtils包(可以直接测通)
(java)oss 文件(视频)上传, 获取回调中的url, 官网地址_pingzhuyan的博客
https://*.oss.......mp4
尝试一下是否可以观看 如果是私有的 需要粘全查看, 公共的直接可以看
将url进行记录保存(丢失的可以去阿里云控制台上操作)
注意: 文章开头说的难点出现了
先在本地测试 路径写死, 测试删除文件 成功
public static void main(String[] args) {
String path ="D:\\software\\workspaceAll\\company\\UseSDK\\alipayctrl\\src\\main\\resources\\static\\pzy\\aaa.txt";
File file = new File(path);
boolean delete = file.delete();
System.out.println(delete);
}
6.1 -> 把升级版的删除 放到 ossutils 的return里面
也就是oss上传 后(无论成功失败) 都执行删除方法
但是惊喜的发现 file.exist 是true delete失败
说明文件删除不了, 首先考虑文件是不是被占用了,调用gc
emm 不是每次执行都会成功 , 依旧存在失败情况
由于 gc不是说执行就执行的 只能通知gc
没办法 只能写个循环 等待gc删除后返回true 退出循环(欢迎大佬指导...这是我能想到的办法)
看第七步----> 解决办法
path参数 是路径的意思(删除)
package sso.util;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
/**
* @Author pzy
* @Version 0.1.0
*/
@Slf4j
public class FileIOUtils {
/**
* @param path
*/
public static boolean fileGCDelete(String path) {
boolean flag = false;
File file1 = new File(path);
if (file1.exists()) {
flag = file1.delete();
try {
for (; ;) {
if (!flag) {
System.gc(); //回收资源
flag = file1.delete();
}
if (flag) break;
}
} catch (Exception e) {
e.printStackTrace();
}
log.debug("路径存在" + flag);
}
return flag;
}
}
System.gc();
// 或者下面,两者等价
Runtime.getRuntime().gc();
//这个跟System.gc相同, 都是等效于第二个
java.lang.management.MemoryMXBean.gc()
代码: [解决方式有多种,这种是递归]
package *;
import java.io.File;
public class PackageDelete {
public static void main(String[] args) {
deleteFileAndFoder("../yang");
}
static void deleteFileAndFoder(String path){
File f=new File(path);
if(f.isDirectory()){//如果是目录,先递归删除
String[] list=f.list();
for(int i=0;i
[除了上传oss的代码demo 其他完成了,自己思路, 做的可能不好,多多包涵 ] pzy