使用minio api實現(xiàn)分片上傳及斷點續(xù)傳功能。
前端準備:獲取大文件的MD5值,將文件分片,5M為一分片,排好順序,并按順序命名(1,2,3這種后面比較好合并)
在上傳分片階段,前端有上傳進度條
1、檢驗文件MD5值
1.1 redis中查看MD5是否存在
String data;
try {
data = customRedisCache.getCacheObject(md5);
} catch (Exception e) {
e.printStackTrace();
}
1.2 判斷臨時文件夾是否存在
boolean d = doesFolderExist(bucket, md5);
/**
* 判斷文件夾是否存在
*
* @param bucketName 存儲桶
* @param objectName 文件夾名稱(去掉/)
* @return true:存在
*/
public boolean doesFolderExist(String bucketName, String objectName) {
boolean exist = false;
try {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
StringBuilder objectNameBuilder = new StringBuilder(objectName);
for (Result<Item> result : results) {
objectNameBuilder.append("/");
Item item = result.get();
if (item.isDir() && objectNameBuilder.toString().equals(item.objectName())) {
exist = true;
}
}
} catch (Exception e) {
exist = false;
}
return exist;
}
1.3 刪除臨時文件夾及其中文件
deleteObject(bucket, md5);
public void deleteObject(String bucketName, String objectName) {
String objectNames = objectName + "/";
try {
if (StringUtils.isNotBlank(objectNames)) {
if (objectNames.endsWith(".") || objectNames.endsWith("/")) {
Iterable<Result<Item>> list = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectNames).recursive(false).build());
list.forEach(e -> {
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(e.get().objectName()).build());
} catch (Exception a) {
return;
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
1.4 上傳文件和上傳分片一樣
InputStream inputStream;
try {
inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(packages)
.object(md5 + "/" + chunk)
.stream(inputStream, file.getSize(), -1)
.contentType("application/x-img")
.build());
} catch (Exception e) {
e.printStackTrace();
return new ResultDto(ResultDto.ERROR, "上傳失敗", chunk);
}
return new ResultDto(ResultDto.SUCCESS, "上傳成功", chunk);
.object(md5 + “/” + chunk) :這種方式在minio里會先創(chuàng)建文件夾
1.5 合并分片
boolean b = merge(bucket, md5, fileName);文章來源:http://www.zghlxwxcb.cn/news/detail-489608.html
/**
* 將塊文件合并到新桶 塊文件必須滿足 名字是 0 1 2 3 5....
*
* @param bucketName 存塊文件的桶
* @param objectName 存新文件的桶
* @param fileName1 存到新桶中的文件名稱
* @return
*/
public boolean merge(String bucketName, String objectName, String fileName1) {
try {
List<ComposeSource> sourceObjectList = new ArrayList<ComposeSource>();
List<Object> folderList = this.getFolderList(bucketName, objectName);
List<String> fileNames = new ArrayList<>();
if (folderList != null && !folderList.isEmpty()) {
for (Object value : folderList) {
Map o = (Map) value;
String name = (String) o.get("fileName");
fileNames.add(name);
}
}
List<Integer> fileNameInt = new ArrayList<>();
List<String> fileNameLast = new ArrayList<>();
if (!fileNames.isEmpty()) {
for (String fileName : fileNames) {
fileNameInt.add(Integer.parseInt(fileName.split("/")[1]));
}
Collections.sort(fileNameInt);
for (int j = 0; j < fileNameInt.size(); j++) {
fileNameLast.add(fileNames.get(j).split("/")[0] + "/" + fileNameInt.get(j));
}
for (String name : fileNameLast) {
sourceObjectList.add(ComposeSource.builder().bucket(bucketName).object(name).build());
}
}
minioClient.composeObject(
ComposeObjectArgs.builder()
.bucket(bucketName)
.object(fileName1)
.sources(sourceObjectList)
.build());
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
//獲取指定bucketName下所有文件 文件名+大小
public List<Object> getFolderList(String bucketName, String objectName) throws Exception {
String objectNames = objectName + "/";
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectNames).recursive(false).build());
Iterator<Result<Item>> iterator = results.iterator();
List<Object> items = new ArrayList<>();
String format = "{'fileName':'%s','fileSize':'%s'}";
while (iterator.hasNext()) {
Item item = iterator.next().get();
items.add(JSON.parse((String.format(format, item.objectName(),
formatFileSize(item.size())))));
}
return items;
}
private static String formatFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString;
String wrongSize = "0B";
if (fileS == 0) {
return wrongSize;
}
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + " B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + " KB";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + " MB";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + " GB";
}
return fileSizeString;
}
1.6 檢驗MD5值
boolean checkMd5 = checkMd5(bucket, fileName, md5);文章來源地址http://www.zghlxwxcb.cn/news/detail-489608.html
private boolean checkMd5(String bucketName, String fileName, String md5) {
try {
//利用apache工具類獲取文件md5值
InputStream inputStream = getInput(bucketName, fileName);
String md5Hex = DigestUtils.md5Hex(inputStream);
if (md5.equalsIgnoreCase(md5Hex)) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
到了這里,關于Minio大文件分片上傳、斷點續(xù)傳實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!