求助:实现与命令行一致的TS/JS tar.gz解压工具,解压结果不匹配
问题:JavaScript解压tar.gz文件与命令行结果不一致
我需要开发一个与命令行效果完全一致的TypeScript(或JavaScript)tar.gz解压工具,但目前遇到解压结果与原文件不匹配的问题:在MacOS命令行使用tar -xzvf解压由Python代码压缩后上传至S3的tar.gz文件时,能得到与原文件大小一致的结果;但在JavaScript中尝试tar-stream、tar、Pako等多种工具时,解压出的文件大小均存在偏差(所有小于10240字节的文件会变为10240字节,部分大文件偏差约50%)。
示例文件:email.zkeyd.tar.gz
可行的非压缩文件处理代码
const store = async function (filename: string) { const link = "https://zkemail-zkey-chunks.s3.amazonaws.com/email.zkeyd"; const resp = await fetch(link, { method: "GET", }); const zkeyBuff = await resp.arrayBuffer(); await localforage.setItem(filename, zkeyBuff); }
有问题的tar.gz处理代码
// Un-targz the arrayBuffer into the filename without the .tar.gz on the end const uncompressAndStore = async function (filename: string) { const link = "https://zkemail-zkey-chunks.s3.amazonaws.com/email.zkeyd.tar.gz"; const resp = await fetch(link, { method: "GET", }); const zkeyBuff = await resp.arrayBuffer(); console.log(`Started to uncompress ${filename}...!`); const extract = tar.extract() // create a tar extract stream const gunzip = zlib.createGunzip(zkeyBuff) // create a gunzip stream from the array buffer gunzip.pipe(extract) // pipe the gunzip stream into the tar extract stream // header is the tar header, stream is the content body (might be an empty stream), call next when you are done with this entry extract.on('entry', function(header: any, stream: any, next: Function) { // decompress the entry data const extractedData: any = [] stream.on('data', function(chunk: any) { extractedData.push(chunk) }) // make sure to call next when the entry is fully processed stream.on('end', function() { next() console.assert(filename.endsWith(zkeyExtension), `Filename doesn't end in ${zkeyExtension}`) const rawFilename = filename.replace(/.tar.gz$/, ""); // save the extracted data to localForage localforage.setItem(rawFilename, extractedData, function(err: Error) { if (err) { console.error(`Couldn't extract data from ${filename}:` + err.message) } else { console.log('Saved extracted file to localForage') } }) }) }) // all entries have been processed extract.on('finish', function() { console.log(`Finished extracting ${filename}`) }) }
Python压缩上传代码
import boto3 import os import tarfile s3 = boto3.client('s3') # Ask Aayush for the access key and secret access key def upload_to_s3(filename, dir=""): with open(dir + filename, 'rb') as file: print("Starting upload...") s3.upload_fileobj(file, bucket_name, filename, ExtraArgs={ 'ACL': 'public-read', 'ContentType': 'binary/octet-stream'}) print("Done uploading!") file = "..." # Create a zip file for the file tar_file_name = file + '.tar.gz' with tarfile.open(tar_file_name, 'w:gz') as tar_file: source_file_path = dir + file print("Compressing: ", source_file_path) tar_file.add(source_file_path, arcname=os.path.basename(source_file_path)) # Upload the zip file to the AWS bucket, overwriting any existing file with the same name upload_to_s3(tar_file_name)
内容的提问来源于stack exchange,提问作者John Targaryen
相关产品推荐
相关产品推荐

