需求:上传文件夹至文件服务器。
比如说:我电脑桌面上的aa文件夹中有一个bb文件夹,bb文件夹中有两个文件,要将选择的文件夹下的文件上传到minio搭建的存储桶中。
思路:
前端传递给后台上传的文件夹下的文件;创建临时文件路径,并将前端传递过来的文件拷贝到创建的临时文件中;获取要上传文件服务器地址;根据临时文件的地址,和文件服务器的地址,以流的方式从临时文件向文件服务器写内容,最终完成上传。
效果:
1:选择文件夹



2:将选择的文件夹上传到文件服务器(我这里的文件服务器是用minio搭建的)



代码实现:
1:前端代码
ps:用户要求文件夹上传时显示一个文件夹的图标而不是input框。所以我的做法是使用样式控制。使用定位,然后将input框设置透明,在贴一个文件夹的icon,icon使用的是elementui提供的。

   

原生的input样式

自定义的文件夹icon

方法实现:

js:

export function uploadFolderList(formData){return request({url: '/aa/bb/cc',method: 'post',data: formData,headers: { "Content-Type": "multipart/form-data" }//设置请求头类型})}

引入js

import { uploadFolderList } from "aa.js";

实现上传文件夹方法

// 上传方法function uploadFiles(event) {let formData = new FormData();let files = [];files = event.target.filesfor (const file of files) {formData.append("files", file);}// 请求后台接口uploadFolderList(formData).then(resp => {if (resp.code === 200) {proxy.$modal.msgSuccess("上传成功");}}).catch((resp) => {proxy.$modal.msgError(resp.msg);})}


后台:
controller:

/** * @description 上传文件夹至存储桶 * @methodName uploadFolderList * @param [request] * @return com.ruoyi.common.core.domain.AjaxResult * @date: 2023/2/14 17:05 * @author ytsj */@PostMapping("/uploadFolderList")public AjaxResult uploadFolderList(HttpServletRequest request) throws IOException {int i = c3MsgGeneratorKeysService.uploadFolderList(request);return i > 0 " />

service层

/** * @description 上传文件夹至存储桶 * @methodName uploadFolderList * @param [map, files] * @return int * @date: 2023/2/14 17:05 * @author ytsj */int uploadFolderList(HttpServletRequest request) throws IOException;

service实现类

 /** * @param [request] * @return int * @description 上传文件夹至存储桶 * @methodName uploadFolderList * @date: 2023/2/15 18:57 * @author ytsj */@Overridepublic int uploadFolderList(HttpServletRequest request) {MultipartHttpServletRequest params = ((MultipartHttpServletRequest) request);//获取文件List files = params.getFiles("files");// 自定义的创建临时文件路径的工具类String workPath = systemTools.joinPath(System.getProperty("ccc.dir"), FOLDER_PATH);String result = "";try {File curFolder = null;for (MultipartFile file : files) {String tempFile = IdUtils.fastUUID();//获取文件的后缀名String suffixName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));String fullPath = HollySystemTools.joinPath(workPath, tempFile) + suffixName;curFolder = new File(workPath);if (!curFolder.exists()) {curFolder.mkdir();}File curFile = new File(fullPath);if (!curFile.exists()) {curFile.createNewFile();}//获取存储桶路径String miniPath = fileConfig.getMinioFileRoot() + file.getOriginalFilename();file.transferTo(curFile.toPath()); //FileCopyUtils.copy(file.getInputStream(),Files.newOutputStream(curFile.toPath())); //上传文件result = uploadFile(fullPath, miniPath);//删除文件curFile.delete();}// 删除文件夹curFolder.delete();} catch (Exception e) {e.printStackTrace();throw new ServiceException("上传文件夹至存储桶失败,请重试!");} finally {if (StringUtils.isNotEmpty(result)) {return 1;} else {return 0;}}}/** * @param [fullPath, minioPath] * @return java.lang.String * @description 根据路径上传文件 * @methodName uploadFile * @date: 2023/2/16 16:41 * @author ytsj */public String uploadFile(String fullPath, String minioPath) {try {// 创建临时文件File scriptFile = new File(fullPath);FileInputStream fileInputStream = new FileInputStream(scriptFile);PutObjectArgs minIOArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(minioPath).stream(fileInputStream, scriptFile.length(), -1).build();ObjectWriteResponse res = this.minioClient.putObject(minIOArgs);fileInputStream.close();//使用完毕后删除临时文件scriptFile.delete();} catch (Exception e) {return "";}return minioPath;}

最终实现了将本地文件夹aa下的所有文件都上传到了存储桶