首页前端工具函数原生JS实现大文件多线程切片

原生JS实现大文件多线程切片

分类前端工具函数时间2024-10-06 10:32:34发布RustStream浏览95
摘要:代码解释 调用多线程(web Worker 进行大文件切片 代码实现 // utils/cutFile.js function cutFile(file { return new Promise((resolve =>{ const chunkSize = 1024 * 1024 * 5 const chunkCount = Math.ceil(file.size / chunkSize const threadChunkCount = Math.ceil(chunkCount / THREAD_COUNT ; // 每个线程负责多少切片任务 const result = []; // 存储返回数据 let finishCount = 0; // 几个线程完成了工作 for (let i = 0; i < THREAD_COUNT; i++ { // 因为需要在worker里面引入辅助函数,所以需要配置一下type: 'module' const worker = new Worker('/src/utils/worker.js', { type: 'module' } let start = i * threadChunkCount; let end = (i + 1 * threadChunkCount; // // 防止超出总的分片数量 if(end <!--autointro-->...

代码解释

调用多线程(web Worker)进行大文件切片

代码实现

// utils/cutFile.js
function cutFile(file){
    return new Promise((resolve)=>{
        const chunkSize = 1024 * 1024 * 5
        const chunkCount = Math.ceil(file.size / chunkSize)
        const threadChunkCount = Math.ceil(chunkCount / THREAD_COUNT); // 每个线程负责多少切片任务
        const result = []; // 存储返回数据
        let finishCount = 0; // 几个线程完成了工作
        for (let i = 0; i < THREAD_COUNT; i++) {
            // 因为需要在worker里面引入辅助函数,所以需要配置一下type: 'module'
            const worker = new Worker('/src/utils/worker.js', {
                type: 'module'
            })
            let start = i * threadChunkCount;
            let end = (i + 1) * threadChunkCount; //
            // 防止超出总的分片数量
            if(end > chunkCount){
                end = chunkCount
            }
            worker.postMessage({
                file,
                chunkSize,
                startChunkIndex: start, // 这个线程处理第几个分片到第几个分片
                endChunkIndex: end
            });
            worker.onmessage = e => {
                for (let i = start; i < end; i++) {
                    result[i] = e.data[i - start]
                }
                worker.terminate();
                finishCount ++;
                if(finishCount == THREAD_COUNT){
                    resolve(result)
                }
            };
        }
    })
}

web Worker文件

// worker.js
import { createChunk } from './index'

self.onmessage = async (e) => {
    const {
        file,
        chunkSize,
        startChunkIndex: start,
        endChunkIndex: end
    } = e.data;
    const proms = [];
    for (let i = start; i < end; i++) {
        proms.push(createChunk(file, i, chunkSize))
    }
    const chunks = await Promise.all(proms)
    // console.log(chunks)
    postMessage(chunks)
}

切片辅助函数

/**
 * 创建文件切片
 * @param file 上传的文件
 * @param index 文件下标
 * @param chunkSize 分片尺寸
 * @returns 返回一个Promise对象,包含(开始下标,结束下标,blob数据,第几个切片)
 */
export function createChunk(file: File, index: number, chunkSize: number){
    return new Promise((resolve) => {
        const start = index * chunkSize;
        const end = start + chunkSize;
        const blob = file.slice(start, end)
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
            resolve({
                start,
                end,
                blob,
                index,
            })
        };
        fileReader.readAsArrayBuffer(blob)
    })
}

扩展

new FileReader() 是用于在客户端(浏览器)中异步读取文件内容的 JavaScript 内置对象。它提供了一种将文件内容读取到内存中以供处理的方式。你可以使用 FileReader 对象来读取不同类型的文件,例如文本文件、图像文件等。

以下是使用 FileReader 的基本步骤:

  1. 创建一个 FileReader 实例:使用 new FileReader() 创建一个新的 FileReader 对象。

  2. 设置事件处理程序:通过设置 onload 事件处理程序,当文件读取完成时,该处理程序将被调用,允许你访问读取的文件内容。

    FileReader提供了一系列事件来处理文件读取的不同阶段:

    1. ‌onload‌:文件读取成功完成时触发
    2. onerror‌:读取过程中发生错误时触发。
    3. onabort‌:读取操作被中断时触发。
    4. onloadstart‌:读取开始时触发。
    5. onprogress‌:读取过程中持续触发。
    6. onloadend‌:读取操作结束时触发,无论成功与否‌
  3. 文件读取:使用文件输入框等方式让用户选择文件,然后通过调用 FileReader 的读取方法(如 readAsText()、readAsDataURL() 等)来读取文件内容。

    ‌readAsText(file)‌:将文件读取为文本。
    ‌readAsDataURL(file)‌:将文件读取为DataURL,适用于图像等小文件。
    ‌readAsArrayBuffer(file)‌:将文件读取为二进制字符串。
    ‌abort()‌:中断读取操作。

本文链接:https://blog.smallhao.fun/?id=10 转载需授权!

分享到:

Chen’Blog版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

VueJavaScript
scss实现网格布局中的移入动画 Vue延迟渲染(defer)优化

游客 回复需填写必要信息
召唤伊斯特瓦尔