1. 使用CompressionStream API实现压缩
这里开启了多线程解压缩
<template><div class="page"><input type="file" placeholder="选择文件" id="file" /><button @click="compress('compress')">压缩</button><button @click="compress('decompress')">解压</button></div>
</template>
<script setup lang="ts">
import { onMounted } from "vue";
let file: File | null = null; //源文件
let file_zip: Blob | null = null; //压缩后的文件
onMounted(() => {document.getElementById("file")?.addEventListener("change", (e: any) => {file = e.target.files[0];console.log("原始文件", file);});
});
let compress = async (type: string) => {const worker = new Worker(new URL("/src/utils/fileWorker.ts", import.meta.url));worker.postMessage({ file: type == "compress" ? file : file_zip, type });worker.onmessage = (e) => {let {data: { file, type },} = e;if (type == "compress") {file_zip = file;console.log("压缩", file);} else {console.log("解压", file);}worker.terminate();};
};
</script>
<style lang="less" scoped></style>
2.线程:
onmessage = async (file: any) => {// 向主线程发送消息let { file: data, type } = file.data;let compressStream;let blob;if (type == "compress") {compressStream = new CompressionStream("gzip");} else {compressStream = new DecompressionStream("gzip");}const readStream = await data?.stream();const compressdReadStream = readStream?.pipeThrough(compressStream);blob = await new Response(compressdReadStream, {headers:type == "compress"? { "Content-Type": "application/gzip" }: { "Content-Type": "text/plain;charset=utf-8" },}).blob();postMessage({ file: blob, type });
};