提问人:Liam Swayne 提问时间:11/17/2023 更新时间:11/17/2023 访问量:19
如何使用客户端 JS 压缩用户上传的用户上传文件夹?
How do you compress a user-uploaded a user-uploaded folder with client-side JS?
问:
我正在创建一个基本页面,该页面使用新的 CompressionStream API gzip 压缩功能来获取用户的文件夹并使用客户端 JS 将其压缩为 .gz。
下面是使用 gzip 进行压缩的示例:
const compressedReadableStream = inputReadableStream.pipeThrough(
new CompressionStream("gzip"),
);
在此示例中,函数使用 gzip 解压缩 blob:
async function DecompressBlob(blob) {
const ds = new DecompressionStream("gzip");
const decompressedStream = blob.stream().pipeThrough(ds);
return await new Response(decompressedStream).blob();
}
我已经让压缩和解压缩适用于文件上传,甚至让它适用于一次上传多个文件,但无法让它适用于目录,这使得它几乎毫无用处。
我尝试创建最基本的设置,但发现将目录压缩为文件只会使其成为文件,而不再是文件文件夹。这是我目前的设置:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload and Compression</title>
</head>
<body>
<input type="file" id="fileInput" multiple webkitdirectory>
<button onclick="groupAndCompress()">Group and Compress</button>
<script>
async function groupAndCompress() {
const fileInput = document.getElementById('fileInput');
const files = fileInput.files;
if (files.length === 0) {
alert('Please select at least one file or folder.');
return;
}
const groupedFiles = groupFiles(files);
const compressedBlob = await compressFiles(groupedFiles);
// You can use the compressedBlob as needed (e.g., download or display)
console.log('Compressed Blob:', compressedBlob);
}
function groupFiles(files) {
const groupedFiles = {};
for (const file of files) {
const path = file.webkitRelativePath || file.name;
if (!(path in groupedFiles)) {
groupedFiles[path] = [];
}
groupedFiles[path].push(file);
}
return groupedFiles;
}
async function compressFiles(groupedFiles) {
const compressedParts = [];
for (const path in groupedFiles) {
const files = groupedFiles[path];
const blobs = await Promise.all(files.map(fileToBlob));
const concatenatedBlob = new Blob(blobs, { type: 'application/zip' });
const compressedStream = concatenatedBlob.stream().pipeThrough(new CompressionStream('gzip'));
const compressedBlob = await new Response(compressedStream).blob();
compressedParts.push(compressedBlob);
}
const finalBlob = new Blob(compressedParts, { type: 'application/zip' });
return finalBlob;
}
function fileToBlob(file) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function () {
resolve(new Blob([reader.result], { type: file.type }));
};
reader.readAsArrayBuffer(file);
});
}
</script>
</body>
</html>
我知道 JSzip,但内置的 Web 功能可以更快地执行此操作,并且不需要获取脚本。
答: 暂无答案
评论