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

时间:2016-06-09 16:42:27

标签: node.js zip

我正在编写一个nodejs脚本,它应该执行以下操作:

  1. 下载zip文件
  2. 删除zip文件的顶级目录(将所有文件移动到一个文件夹中)
  3. 上传新的zip文件
  4. 由于zip文件相当大,我想重命名(或移动)文件而不解压缩并重新传输文件。

    这可能吗?

2 个答案:

答案 0 :(得分:3)

是的,这是可能的 使用像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。这包括路径
  2. 使用fileName
  3. 读取文件内容
  4. 删除顶级目录名称以获取newFileName
  5. 将第2步中的fileContent添加到newZip,为其提供步骤3中的newFileName
  6. 最后,将newZip写出来给它一个新的zipName
  7. 希望有所帮助

答案 1 :(得分:0)

您可以使用具有异步承诺风格的出色 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');

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