JS 实现文件的切割与合并

1,914 阅读1分钟

前端页面展示:

<div>
    <input type="file" id="filel">
    <button id="btn1">拆分</button>
  </div>
  <br>
  <div>
    <input type="file" multiple id="file2">
    <button id="btn2">合并</button>
  </div>

image.png

拆分功能

    document.getElementById('btn1').onclick = () => {
        const files = document.getElementById('file1').files
        const file = files[0]
        const uploadSize = 1024 * 1024 * 10
        const arr = []
        for(let i=0;i<file.size;i+=uploadSize) {
            const index = parseInt(i / uploadSize) + 1
            arr.push(file.slice(i, uploadSize * index))
        }
        downloadFiles(arr, file.name)
    }

这里说明下拆分函数的一些变量,并在浏览器控制台输出: image.png

files: 文件列表,可以选择上传多个文件(一般一次上传一个文件)

image.png

file: 获取到上传的第一个文件( files[0] )

image.png

uploadSize(1024 * 1024 * 10): 切片的大小,每个切片10M

这里使用25M左右的文件模拟大文件,输出切片数组(arr)

image.png

下载文件

    // 下载一个文件
    function downloadFile(v, name) {
        const a = document.createElement('a')
        a.setAttribute('download', name)
        a.href = URL.createObjectURL(v)
        a.click()
    }
    // 下载多个文件
    function downloadFiles(arr, name) {
        arr.forEach((v, i) => {
            downloadFile(v, name + '-' + i)
        })
    }

点击拆分按钮时,浏览器会下载拆分好的文件到本地 image.png

合并功能

    document.getElementById('btn2').onclick = () => {
        const files = document.getElementById('file2').files
        const arr = [...files].map(v => {
            return v.slice(0, v.size)
        })
        const name = files[0].name.replace(/-\d+$/, '')
        const file = new File(arr, name)
        downloadFile(file, file.name)
    }

选择所有切片进行上传

image.png

前端显示3个文件已上传

image.png

点击合并按钮,自动下载合并后的文件到本地

image.png

点击播放视频时正常,说明文件的切割与合并没有问题

这里说明下合并函数的一些变量,在浏览器控制台输出:

image.png

arr: 即切片数组

image.png

file: 合并后的文件(这里使用了 File对象)

image.png

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件切割与合并</title>
</head>
<body>
    <div>
        <input type="file" id="file1">
        <button id="btn1">拆分</button>
    </div>
    <br>
    <div>
        <input type="file" multiple id="file2">
        <button id="btn2">合并</button>
    </div>
</body>
<script>
    const loadingEl = document.getElementById('loading')
    document.getElementById('btn1').onclick = () => {
        const files = document.getElementById('file1').files
        const file = files[0]
        const uploadSize = 1024 * 1024 * 10
        const arr = []
        for(let i=0;i<file.size;i+=uploadSize) {
            const index = parseInt(i / uploadSize) + 1
            arr.push(file.slice(i, uploadSize * index))
        }
        console.log('文件切片', arr)
        downloadFiles(arr, file.name)
    }
    document.getElementById('btn2').onclick = () => {
        const files = document.getElementById('file2').files
        const arr = [...files].map(v => {
            return v.slice(0, v.size)
        })
        const name = files[0].name.replace(/-\d+$/, '')
        const file = new File(arr, name)
        downloadFile(file, file.name)
    }
    function downloadFiles(arr, name) {
        arr.forEach((v, i) => {
            downloadFile(v, name + '-' + i)
        })
    }
    function downloadFile(v, name) {
        const a = document.createElement('a')
        a.setAttribute('download', name)
        a.href = URL.createObjectURL(v)
        a.click()
    }
</script>
</html>