在nodejs中重命名zip存档中的文件

bmvo0sr5  于 2023-06-29  发布在  Node.js
关注(0)|答案(3)|浏览(139)

我正在编写一个nodejs脚本,它应该执行以下操作:
1.下载zip文件
1.删除zip文件的顶级目录(将所有文件向上移动一个文件夹)
1.上传新的zip文件
因为压缩文件是相当大的,我想重命名(或移动)的文件,而不解压和重新压缩文件。
这可能吗?

smdnsysy

smdnsysy1#

是的,可以使用像adm-zip这样的库

var AdmZip = require('adm-zip');

//create a zip object to hold the new zip files
var newZip = new AdmZip();

// reading archives
var zip = new AdmZip('somePath/download.zip');
var zipEntries = zip.getEntries(); // an array of ZipEntry records

zipEntries.forEach(function(zipEntry) {
    var fileName = zipEntry.entryName;
    var fileContent = zip.readAsText(fileName)
    //Here remove the top level directory
    var newFileName = fileName.substring(fileName.indexOf("/") + 1);

    newZip.addFile(newFileName, fileContent, '', 0644 << 16);        
});

newZip.writeZip('somePath/upload.zip');  //write the new zip

算法
创建一个newZip对象来临时保存内存中的文件读取下载的zip中的所有条目。对于每个条目
1.读取fileName。这包括路径
1.使用fileName读取文件内容
1.删除顶级目录名以获取newFileName
1.将步骤2中的fileContent添加到newZip中,并将步骤3中的newFileName赋予它
1.最后,将newZip写入磁盘,并给它一个新的zipName
希望能帮上忙

06odsfpq

06odsfpq2#

你可以使用async-promise风格的jszip库。

import jszip from 'jszip';
import fs from 'fs';

/**
 * Move/rename entire directory tree within a zip.
 * @param {*} zipFilePath The original zip file
 * @param {*} modifiedZipFilePath The path where palace the modified zip 
 * @param {*} originalDir The original directory to change
 * @param {*} destinationDir The new directory to move to.
 */
async function moveDirectory(zipFilePath, modifiedZipFilePath, originalDir, destinationDir) {

    // Read zip file bits buffer
    const zipFileBuffer = await fs.promises.readFile(zipFilePath);
    // Load jszip instance
    const zipFile = await jszip.loadAsync(zipFileBuffer);
    // Get the original directory entry
    const originalDirContent = zipFile.folder(originalDir);
    // Walk on all directory tree
    originalDirContent.forEach((path, entry) => {
        // If it's a directory entry ignore it.
        if (entry.dir) {
            return;
        }
        // Extract the file path within the directory tree 
        const internalDir = path.split(originalDir)[0];
        // Build the new file directory in the new tree 
        const newFileDir = `${destinationDir}/${internalDir}`;
        // Put the file in the new tree, with the same properties
        zipFile.file(newFileDir, entry.nodeStream(), { 
            createFolders: true,
            unixPermissions: entry.unixPermissions,
            comment: entry.comment,
            date: entry.date,
        });
    });
    // After all files copied to the new tree, remove the original directory tree.
    zipFile.remove(originalDir);
    // Generate the new zip buffer
    const modifiedZipBuffer = await zipFile.generateAsync({ type: 'nodebuffer' });
    // Save the buffer as a new zip file
    await fs.promises.writeFile(modifiedZipFilePath, modifiedZipBuffer);
}

moveDirectory('archive.zip', 'modified.zip', 'some-dir/from-dir', 'some-other-dir/to-dir');

这只是遍历所有原始目录树条目,并将它们放置在新目录树中。

shstlldc

shstlldc3#

创建Vitalis答案的编辑答案,因为有太多的编辑待处理。

const AdmZip = require('adm-zip');

// create a zip object to hold the new zip files
const newZip = new AdmZip();

// read existing zip
const oldZip = new AdmZip('somePath/download.zip');
const zipEntries = oldZip.getEntries(); // an array of ZipEntry records

zipEntries.forEach(function(zipEntry) {
  let oldEntryName = zipEntry.entryName;
  let fileContent = oldZip.readFile(oldEntryName) || Buffer.alloc(0);
  // remove the top level directory
  let newEntryName = oldEntryName.substring(oldEntryName.indexOf("/") + 1);

  newZip.addFile(newEntryName, fileContent);        
});

newZip.writeZip('somePath/upload.zip');  //write the new zip

commentattr参数对于newZip.addFile()是可选的。实际上,0644 << 16应该写成0o644 << 16,并且在解压缩zip文件时,它还拒绝您读取文件。
fileContent需要是一个缓冲区,而不是一个字符串。如果在不太可能的情况下,条目可疑地从旧zip文件中消失,则会给出一个回退(Buffer.alloc(0))。

相关问题