原生JS实现大文件多线程切片
摘要:代码解释 调用多线程(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 的基本步骤:
创建一个 FileReader 实例:使用 new FileReader() 创建一个新的 FileReader 对象。
设置事件处理程序:通过设置 onload 事件处理程序,当文件读取完成时,该处理程序将被调用,允许你访问读取的文件内容。
FileReader提供了一系列事件来处理文件读取的不同阶段:
- onload:文件读取成功完成时触发
- onerror:读取过程中发生错误时触发。
- onabort:读取操作被中断时触发。
- onloadstart:读取开始时触发。
- onprogress:读取过程中持续触发。
- onloadend:读取操作结束时触发,无论成功与否
文件读取:使用文件输入框等方式让用户选择文件,然后通过调用 FileReader 的读取方法(如 readAsText()、readAsDataURL() 等)来读取文件内容。
readAsText(file):将文件读取为文本。
readAsDataURL(file):将文件读取为DataURL,适用于图像等小文件。
readAsArrayBuffer(file):将文件读取为二进制字符串。
abort():中断读取操作。
本文链接:https://blog.smallhao.fun/?id=10 转载需授权!
Chen’Blog版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!