我正在编写一个nodejs脚本,它应该执行以下操作:
- 下载zip文件
- 删除zip文件的顶层目录(将所有文件移动到上一级文件夹)
- 上传新的zip文件
没问题,可以使用像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
算法
创建一个新的Zip对象来临时存储文件在内存中
读取下载的zip文件中的所有条目。对于每个条目,执行以下操作
希望这有所帮助
您可以使用优秀的jszip库,以异步Promise方式进行操作。
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');
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
comment
和attr
参数对于newZip.addFile()
来说是可选的。事实上,0644 << 16
应该写成0o644 << 16
,当压缩文件被解压时,它还会禁止您读取该文件。
fileContent
需要是一个缓冲区而不是字符串。在旧的压缩文件中,如果不幸地发生条目异常消失的情况,将提供一个回退选项(Buffer.alloc(0)
)。