如何在Perl中归档目录

如何在Perl中归档目录,perl,Perl,我正在尝试归档一个包含所有子目录和文件的目录。但是下面的代码不能正常工作。它只是归档了文件和文件夹,而不是文件夹的内容!我怎样才能解决这个问题 my @files = glob( $BACKUP_PATH.'website/*' ); my $tar = Archive::Tar->new(); $tar->add_files(@files); my $date = DateTime->now(time_zone=>"local"); $tar->write($B

我正在尝试归档一个包含所有子目录和文件的目录。但是下面的代码不能正常工作。它只是归档了文件和文件夹,而不是文件夹的内容!我怎样才能解决这个问题

my @files = glob( $BACKUP_PATH.'website/*' );
my $tar = Archive::Tar->new();
$tar->add_files(@files);

my $date = DateTime->now(time_zone=>"local");
$tar->write($BACKUP_PATH.$websiteFolderName."/".$date->dmy('-')."-".$websiteFolderName.".tar");
glob
()不会递归到子目录中。您需要自己解决这个问题,或者使用以下模块:


我想我应该写一个简单的版本,因为我对被接受的解决方案非常失望。我想我会告诉你什么是可能的,什么是我认为合适的

我已经做了这些改变

  • 我正在使用获取文件名的日期戳。它是一个核心模块,是生成
    %d-%m-%Y
    日期戳所需的全部功能。是非核心的,并且为了这样一个简单的目的需要加载大量的代码

    顺便说一下,我使用了
    ymd
    格式,而不是
    dmy
    。如果你想用你自己编写代码的方式来写,那么你可以把它改回去,但是
    ymd
    名字很有用,因为它们是按日期顺序排序的

  • 我使用了核心库的过程接口
    catdir
    catfile
    from。这样就不用担心一个变量的末尾是否有斜杠,另一个变量的开头是否有斜杠,而且代码更清晰,因为这样可以避免所有讨厌的字符串串联

  • 我使用了
    make_path
    from来确保目标目录实际存在

  • 由于要归档文件的路径存储在一个数组中,因此没有理由不使用
    create\u archive
    class方法一次性生成和保存文件

    create\u archive
    的第二个参数是压缩方法。我已将其设置为零以请求无压缩和最大速度,但您可以通过传递
    COMPRESS\u gzip
    COMPRESS\u bzip
    来启用gzip或bzip压缩

    尽管模块的文档不鼓励这样做,但您也可以将此参数设置为1到9,以指示gzip压缩级别。如果您正在存档文本文件,那么我强烈建议您在此处使用1或2。传递
    COMPRESS\u GZIP
    会导致GZIP压缩级别为9,这是迄今为止最慢的压缩级别,并且通常会导致文件比较低压缩级别大。值为1时,文件大小通常为未压缩归档文件的三分之一,而值为2时,文件大小可能会再减少5%。在那之后,通常收获很少

  • 我添加了一些日志消息,以增强信心并告知计划的进度。我还编写了一个小的
    bytes
    子例程,将文件大小转换为1KB的适当幂,使其更具可读性

我之所以使用Windows路径,是因为我正好坐在这张桌子上。因为使用了
File::Spec
,一旦在代码顶部设置了路径和文件名,它在Linux上也可以正常工作+

不管你是否使用这个,我希望你觉得它有用

使用严格;
使用警告;
使用归档::Tar;
使用File::Find qw/Find/;
使用时间::件;
使用File::Spec::Functions qw/catfile catdir/;
使用File::Path qw/make_Path/;
标准输出->自动刷新;
my$BACKUP_PATH='E:/Perl';
我的$WEBITE_文件夹_名称='WEBITE';
my$website_backup_name='website_backup';
打印“制作要存档的文件列表\n”;
我的$source\u dir=catdir($BACKUP\u PATH,$website\u folder\u name);
我的@filelist;
查找(子对象){
除非-f,否则返回;
推送@filelist,$File::Find::name;
},$source_dir);
printf“列出完整的-%d个要存档的文件\n”,scalar@filelist;
my$tardir=catdir($BACKUP\u PATH,$website\u BACKUP\u name);
生成路径($tardir,{verbose=>1});
my$date=localtime()->ymd;
my$tarfile=catfile($tardir,“$date-$website\u backup\u name.tar”);
打印qq{将存档文件写入“$tarfile”\n};
my$success=Archive::Tar->create_Archive($tarfile,0,@filelist);
printf“存档成功写入-%s\n”,字节(-s$tarfile),如果$success;
子字节{
我的($尺码)=@;
my@prefix=('',qw/kmgtpe/);
我的$pow=0;
而($size>=1024){
$size/=1024;
++$pow;
}
sprintf“%.0f%sB”,$size,$prefix[$pow];
}
输出
制作要归档的文件列表
列表完成-6602个要归档的文件
正在将归档文件写入“E:\Perl\website\u backup\2016-01-07-website\u backup.tar”
已成功写入存档文件-7MB

我不认为这是重复的。另一个问题是如何使用Archive::Tar。这个问题已经有了,但是OP的实现中的逻辑有问题。您是否检查了
@文件
中包含的内容?您是否在调试器中完成了此操作?这是开始的地方,它不起作用。它抛出一个错误:无法统计。。。。。在第24行的test.pl中没有这样的文件或目录:第-->行-->查找({通缉……”复仇:是的,对不起-愚蠢的复制/粘贴错误,尾随的
/*
必须删除。或者,更好的是:不是我的否决票,但你**省略
使用严格的
使用警告“全部”
**省略
使用日期时间
**不要声明或定义
$BACKUP\u PATH
$websiteFolderName
**Bu具有字符串浓缩的ild文件路径**不测试您的solution@Borodin:谢谢你的意见。
use Archive::Tar;
use File::Find qw(find);

my @files;
find( { wanted => sub { push @files, $File::Find::name } }, $BACKUP_PATH.'website');
my $tar = Archive::Tar->new();
$tar->add_files( @files );

my $date = DateTime->now(time_zone=>"local");
$tar->write($BACKUP_PATH.$websiteFolderName."/".$date->dmy('-')."-".$websiteFolderName.".tar");