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 });
};