整体代码放在最后的
总体思路:
第一步:
读取这个文件夹的所有文件对象
这里主要时为了我们下一步递归准备参数
/**bucketName为桶名称
* folderPath为文件夹的在桶中路径
*/
ListObjectsArgs listObjectsArgs=ListObjectsArgs.builder().bucket(bucketName).prefix(folderPath).build();
第二步:
递归查找文件对象
这里的思路为,遇到文件夹,就读取这个文件夹的所有文件对象,进入递归.遇到文件,将文件的objectName存放到list中,objectName就是文件路径.最终得到整个文件夹所有文件的路径的fileUrlList.
private List<String> findAndSaveFileList(ListObjectsArgs listObjectsArgs,String bucketName ) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
List<String> fileObjectsList =new ArrayList<>();
Iterable<Result<Item>> results = coreClient.minioClient.listObjects(listObjectsArgs);
for (Result<Item> result : results) {
Item item = result.get();
if (item.isDir()) {
log.info("即将下载的文件路径:{}",item.objectName());
ListObjectsArgs args = ListObjectsArgs.builder().bucket(bucketName).prefix(item.objectName()).build();
List<String> list=findAndSaveFileList(args,bucketName);
fileObjectsList.addAll(list);
} else {
fileObjectsList.add(item.objectName());
}
}
return fileObjectsList;
}
第三步:
准备文件输入流
根据第二步的文件路径的list,准备对应数量的文件输入流数组.然后遍历文件路径的list,去minio里面读取对应的文件输入流,将其放到文件输入流数组
InputStream[] srcFiles = new InputStream[fileUrlList.size()];
//files name
for (int i = 0; i < fileUrlList.size(); i++) {
String fileUrl = fileUrlList.get(i);
InputStream inputStream = coreClient.minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object(fileUrl)
.build());
if (inputStream == null) {
continue;
}
log.info("正在下载文件:{}",fileUrlList.get(i));
srcFiles[i] = inputStream;
}
第四步
将文件输入流压缩,边压缩边返回
这里遍历文件输入流数组,准备压缩,压缩后的路径设置为第二步中的文件路径,这样压缩处理的文件路径和minio路径保持一致
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("file.zip", "UTF-8"));
ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
for (int i = 0; i < srcFiles.length; i++) {
InputStream srcFile=srcFiles[i];
String filePath=fileUrlList.get(i);
log.info("正在压缩文件:{}",fileUrlList.get(i));
compressFile(srcFile,filePath,zipOutputStream);
}
zipOutputStream.flush();
zipOutputStream.close();
完整代码:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
package cn.test.nvh.domain;
import cn.csdn.source.minio.config.MinIOClientConfig;
import io.minio.GetObjectArgs;
import io.minio.ListObjectsArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.errors.*;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author:
* @description:
* @date: 2024/9/27 16:30
*/
@Component
@Slf4j
public class download {
@Autowired
private MinIOClientConfig minIOClientConfig;
private MinioClient minioClient;
private MinioClient getCoreClient(){
if(minioClient==null){
minioClient=MinioClient.builder()
.endpoint(minIOClientConfig.getEndpoint())
.credentials(minIOClientConfig.getAccessKey(), minIOClientConfig.getSecretKey())
.build();
}
return minioClient;
}
public void downloadFolder(String folderPath, String bucketName, HttpServletResponse response) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
if(folderExists(folderPath,bucketName)) {
ListObjectsArgs listObjectsArgs=ListObjectsArgs.builder().bucket(bucketName).prefix(folderPath).build();
List<String> fileUrlList = findAndSaveFileList(listObjectsArgs,bucketName);
//files InputStream
InputStream[] srcFiles = new InputStream[fileUrlList.size()];
//files name
for (int i = 0; i < fileUrlList.size(); i++) {
String fileUrl = fileUrlList.get(i);
InputStream inputStream = getCoreClient().getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object(fileUrl)
.build());
if (inputStream == null) {
continue;
}
log.info("正在下载文件:{}",fileUrlList.get(i));
srcFiles[i] = inputStream;
}
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("file.zip", "UTF-8"));
ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
for (int i = 0; i < srcFiles.length; i++) {
InputStream srcFile=srcFiles[i];
String filePath=fileUrlList.get(i);
log.info("正在压缩文件:{}",fileUrlList.get(i));
compressFile(srcFile,filePath,zipOutputStream);
}
zipOutputStream.flush();
zipOutputStream.close();
}
}
public boolean folderExists(String folderPath,String bucketName) {
ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
.bucket(bucketName).prefix(folderPath)
.recursive(false).build();
Iterable<Result<Item>> iterable = getCoreClient().listObjects(listObjectsArgs);
// 不为空则说明是文件夹
return iterable.iterator().hasNext();
}
private List<String> findAndSaveFileList(ListObjectsArgs listObjectsArgs,String bucketName ) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
List<String> fileObjectsList =new ArrayList<>();
Iterable<Result<Item>> results = getCoreClient().listObjects(listObjectsArgs);
for (Result<Item> result : results) {
Item item = result.get();
if (item.isDir()) {
log.info("即将下载的文件路径:{}",item.objectName());
ListObjectsArgs args = ListObjectsArgs.builder().bucket(bucketName).prefix(item.objectName()).build();
List<String> list=findAndSaveFileList(args,bucketName);
fileObjectsList.addAll(list);
} else {
fileObjectsList.add(item.objectName());
}
}
return fileObjectsList;
}
private void compressFile(InputStream inputStream,String path, ZipOutputStream zipOutputStream) throws IOException {
try {
ZipEntry ze = new ZipEntry(path);
zipOutputStream.putNextEntry(ze);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, len);
}
}catch (Exception e){
log.error(e.getMessage());
log.error("读取文件失败");
}
}
}
请注意,minIOClientConfig为自己配置minio配置类,需要配置
endpoint
accessKey
secretKey
fileHost
等信息,这块根据用户自己的配置进行修改和配置,我这就不提供了
.最后感谢你的点赞和收藏!!