使用archiver.js(用于Node.js),我需要从递归(多子目录)存档中排除图像。这是我的代码:
const zip = archiver('zip', { zlib: { level: 9 } });
const output = await fs.createWriteStream(`backup/${fileName}.zip`);
res.setHeader('Content-disposition', `attachment; filename=${fileName}.zip`);
res.setHeader('Content-type', 'application/download');
output.on('close', function () {
res.download(`backup/${fileName}.zip`, `${fileName}.zip`);
});
output.on('end', function () {
res.download(`backup/${fileName}.zip`, `${fileName}.zip`);
});
zip.pipe(output);
zip.glob('**/*',
{
cwd: 'user_uploads',
ignore: ['*.jpg', '*.png', '*.webp', '*.bmp'],
},
{});
zip.finalize();
问题在于它没有排除忽略文件。我可以请求语法帮助吗?
Archiver使用Readdir-Glob进行glob匹配,该匹配使用minimatch进行匹配。
Readdir-Glob(node-readdir-glob/index.js#L147
)中的匹配是针对包括路径名在内的完整文件名完成的,它不允许我们应用该选项matchBase
,而该选项将只不过是完整路径的基本名称。
您可以使用glob否定符将glob表达式转换为排除不希望包含在存档文件中的所有文件扩展名!(...)
,并且它将包含除与否定表达式匹配的内容以外的所有内容:
zip.glob(
'**/!(*.jpg|*.png|*.webp|*.bmp)',
{
cwd: 'user_uploads',
},
{}
);
为了使minimatch在我们无法设置该matchBase
选项的情况下起作用,我们必须包括匹配的目录glob才能使其起作用:
zip.glob(
'**/*',
{
cwd: 'user_uploads',
ignore: ['**/*.jpg', '**/*.png', '**/*.webp', '**/*.bmp'],
},
{}
);
关于选项,Readdir-Glob的这种行为有点令人困惑ignore
:
ignore
:Glob模式或Glob模式数组可排除匹配项。如果文件或文件夹至少与提供的一种模式匹配,则不会返回。它不会阻止文件夹内容中的文件被返回。
这意味着igrore
项目必须是实际的全局表达式,必须包含整个路径/文件表达式。当我们指定时*.jpg
,它将仅匹配根目录中的文件,而不匹配子目录中的文件。如果我们想将JPG文件排除在目录树的深处,则必须使用“包括所有目录”模式以及文件扩展名模式来做到这一点**/*.jpg
。
如果只想在特定子目录中排除某些文件扩展名,则可以使用如下所示的否定模式将子目录添加到路径中:
// The glob pattern '**/!(Subdir)/*.jpg' will exclude all JPG files,
// that are inside any 'Subdir/' subdirectory.
zip.glob(
'**/*',
{
cwd: 'user_uploads',
ignore: ['**/!(Subdir)/*.jpg'],
},
{}
);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句