在nodejs中重命名zip存档内的文件
Rename files inside zip archive in nodejs
我正在编写一个应该执行以下操作的 nodejs 脚本:
- 下载 zip 文件
- 删除 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
算法
创建一个 newZip 对象来临时将文件保存在内存中
阅读下载的 zip 中的所有条目。对于每个条目
- 读取文件名。这包括路径
- 使用文件名读取文件内容
- 去掉顶层目录名得到新文件名
- 将步骤 2 中的文件内容添加到 newZip,为其提供步骤 3 中的新文件名
- 最后,将 newZip 写到磁盘,给它一个新的 zipName
希望对您有所帮助
您可以使用具有异步承诺风格的优秀 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');
这只是遍历所有原始目录树条目并将它们放入新目录树中。
我正在编写一个应该执行以下操作的 nodejs 脚本:
- 下载 zip 文件
- 删除 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
算法
创建一个 newZip 对象来临时将文件保存在内存中
阅读下载的 zip 中的所有条目。对于每个条目
- 读取文件名。这包括路径
- 使用文件名读取文件内容
- 去掉顶层目录名得到新文件名
- 将步骤 2 中的文件内容添加到 newZip,为其提供步骤 3 中的新文件名
- 最后,将 newZip 写到磁盘,给它一个新的 zipName
希望对您有所帮助
您可以使用具有异步承诺风格的优秀 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');
这只是遍历所有原始目录树条目并将它们放入新目录树中。