前端代码

  1. 引入 Layui 库和 jQuery 库
<!-- 引入 Layui 库 -->
<link rel='stylesheet' href='layui/css/layui.css'>
<script src='layui/layui.all.js'></script>

<!-- 引入 jQuery 库 -->
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
  1. 构建上传表单
<form class='layui-form' action='' enctype='multipart/form-data'>
  <div class='layui-form-item'>
    <div class='layui-upload'>
      <button type='button' class='layui-btn' id='uploadBtn'>上传文件</button>
      <input type='file' name='file' class='layui-upload-file' id='fileInput'>
    </div>
  </div>
</form>
  1. 编写上传文件的 JavaScript 代码
layui.use(['layer', 'upload'], function() {
    var layer = layui.layer,
        upload = layui.upload;

    var fileMd5 = ''; // 文件 MD5 值

    // 计算文件 MD5 值
    function calcFileMd5(file, callback) {
        var fileSize = file.size;
        var chunkSize = 1024 * 1024; // 1MB
        var chunks = Math.ceil(fileSize / chunkSize);
        var currentChunk = 0;
        var spark = new SparkMD5.ArrayBuffer();
        var fileReader = new FileReader();

        fileReader.onload = function(e) {
            spark.append(e.target.result);
            currentChunk++;
            if (currentChunk < chunks) {
                loadNextChunk();
            } else {
                var md5 = spark.end();
                callback(md5);
            }
        };

        function loadNextChunk() {
            var start = currentChunk * chunkSize;
            var end = Math.min(start + chunkSize, fileSize);
            fileReader.readAsArrayBuffer(file.slice(start, end));
        }

        loadNextChunk();
    }

    // 上传文件
    upload.render({
        elem: '#uploadBtn',
        url: '/upload',
        auto: false,
        bindAction: '#submitBtn',
        choose: function(obj) {
            var file = obj.pushFile();
            calcFileMd5(file, function(md5) {
                fileMd5 = md5;
                obj.preview(function(index, file, result) {
                    $('#fileInput').val(file.name);
                    layer.msg('文件已选择');
                });
            });
        }
    });

    // 提交表单
    $('#submitBtn').on('click', function() {
        var formData = new FormData();
        formData.append('fileMd5', fileMd5);
        formData.append('file', $('#fileInput')[0].files[0]);
        $.ajax({
            url: '/upload',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(res) {
                layer.msg('文件上传成功');
            },
            error: function(xhr, status, error) {
                layer.msg('文件上传失败');
            }
        });
    });
});

后端代码

  1. 创建上传接口
@RequestMapping("/upload")
public Result upload(HttpServletRequest request) {
    String fileMd5 = request.getParameter("fileMd5");
    File file = new File("upload/" + fileMd5);
    if (!file.exists()) {
        file.mkdirs();
    }

    String fileName = request.getParameter("fileName");
    int chunkIndex = Integer.parseInt(request.getParameter("chunkIndex"));

    try (InputStream inputStream = request.getInputStream();
         OutputStream outputStream = new FileOutputStream(new File(file, fileName + "." + chunkIndex))) {
        byte[] buffer = new byte[1024 * 1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
        return Result.fail("文件上传失败");
    }

    return Result.success();
}
  1. 创建合并文件接口
@RequestMapping("/merge")
public Result merge(HttpServletRequest request) {
    String fileMd5 = request.getParameter("fileMd5");
    String fileName = request.getParameter("fileName");
    int chunkCount = Integer.parseInt(request.getParameter("chunkCount"));

    File file = new File("upload/" + fileMd5);
    File[] files = file.listFiles((dir, name) -> name.startsWith(fileName + "."));

    if (files.length != chunkCount) {
        return Result.fail("分片数量不正确");
    }

    File destFile = new File("upload/" + fileName);
    try (OutputStream outputStream = new FileOutputStream(destFile)) {
        for (int i = 0; i < chunkCount; i++) {
            File chunkFile = new File(file, fileName + "." + i);
            try (InputStream inputStream = new FileInputStream(chunkFile)) {
                byte[] buffer = new byte[1024 * 1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return Result.fail("文件合并失败");
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        return Result.fail("文件合并失败");
    }

    return Result.success();
}
Java+Layui 实现大文件分片上传前后端代码详解

原文地址: https://www.cveoy.top/t/topic/nIId 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录