Minio大文件分片上传、断点续传实现

这篇具有很好参考价值的文章主要介绍了Minio大文件分片上传、断点续传实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用minio api实现分片上传及断点续传功能。
前端准备:获取大文件的MD5值,将文件分片,5M为一分片,排好顺序,并按顺序命名(1,2,3这种后面比较好合并)

Minio大文件分片上传、断点续传实现

在上传分片阶段,前端有上传进度条
Minio大文件分片上传、断点续传实现
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里会先创建文件夹

1.5 合并分片
boolean b = merge(bucket, md5, fileName);

 /**
     * 将块文件合并到新桶   块文件必须满足 名字是 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);文章来源地址https://www.toymoban.com/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大文件分片上传、断点续传实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端文件上传(文件上传,分片上传,断点续传)

    普通文件上传 思路: 首先获取用户选择的文件对象,并将其添加到一个 FormData 对象中。然后,使用 axios 的 post 方法将 FormData 对象发送到服务器。在 then 和 catch 中,我们分别处理上传成功和失败的情况,并输出相应的信息。 需要注意,在使用 axios 进行文件上传时,必须将

    2024年02月22日
    浏览(43)
  • 上传视频文件,基于断点续传(整合Minio)

    目录 1、什么是断点续传 2、分块文件 3、合并文件 4、 Minio 分布式文件系统整合断点续传 4.1 进行文件分块上传到 Minio  4.2 进行 Minio 中分块文件的合并 5、使用 Minio 进行断点续传的注意事项           相信很多小伙伴在上传下载图片或者视频的时候,突然间(没错就是这

    2024年02月11日
    浏览(48)
  • 【万字长文】Vue+SpringBoot实现大文件秒传、断点续传和分片上传完整教程(提供Gitee源码)

    前言:最近在实际项目中碰到一个需求,客户可能会上传比较大的文件,如果采用传统的文件上传方案可能会存在服务器压力大、资源浪费甚至内存溢出的一些安全风险,所以为了解决一系列问题,需要采用新的技术方案来实现大文件的上传;空闲的时候参考了网上的一些相

    2024年02月12日
    浏览(47)
  • spring boot 阿里云oss 文件分片上传、断点续传

    文章目录 前言 一、申请阿里云oss 二、上代码 总结       阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。     您可以使用阿

    2024年02月07日
    浏览(50)
  • 前端 + 后端 实现分片上传(断点续传/极速秒传)

    先记录下,后面有时间再去实现 (已实现,可参考 SpringBoot+vue文件上传下载预览大文件分片上传文件上传进度 SpringBoot+vue 大文件分片下载) 可参考链接:vue上传大文件/视频前后端(java)代码 前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当接受完最后

    2023年04月17日
    浏览(51)
  • 大文件上传阿里云oss,分片、断点续传进度条展示

    前端页面展示 大文件如果不采用分片上传会导致卡死、内存占用过高导致程序奔溃等一些列问题。 通常在文件大于100 MB的情况下,建议采用分片上传的方法,通过断点续传和重试,提高上传成功率。如果在文件小于100 MB的情况下使用分片上传,且partSize设置不合理的情况下,

    2024年02月11日
    浏览(45)
  • SpringBoot + minio实现分片上传、秒传、续传

    MinIO是一个基于Go实现的高性能、兼容S3协议的对象存储。它采用GNU AGPL v3开源协议,项目地址是https://github.com/minio/minio。 引用官网: MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工

    2024年02月08日
    浏览(55)
  • springboot整合vue2-uploader文件分片上传、秒传、断点续传

    vue-simple-uploader 是基于 simple-uploader.js 封装的vue上传插件。它的优点包括且不限于以下几种: 支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传 可暂停、继续上传 错误处理 支持“秒传”,通过文件判断服务端是否已存在从而实现“秒传” 分片上传 支持进度、预估

    2024年02月06日
    浏览(61)
  • 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传

    1. 前言 文件上传 小文件(图片、文档、视频)上传可以直接使用很多ui框架封装的上传组件,或者自己写一个input 上传,利用FormData 对象提交文件数据,后端使用spring提供的MultipartFile进行文件的接收,然后写入即可。但是对于比较大的文件,比如上传2G左右的文件(http上传

    2024年02月06日
    浏览(48)
  • springboot 、html分片上传,断点续传

    后端代码 注意:合并分片代码中: Files.write(mergedFilePath, Files.readAllBytes(chunkFilePath), StandardOpenOption.APPEND); 如果不设置该值 StandardOpenOption.APPEND ,无法打开合并后的文件 前端代码

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包