我正在尝试使用所有子目录和文件归档目录。但是下面的代码无法正常工作。它只是归档文件和文件夹,而不是文件夹的内容!我该如何解决这个问题?
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");
答案 0 :(得分:2)
我以为我写了一个钟声和口哨版本,因为我对公认的解决方案感到非常失望。我以为我会告诉你什么是可能的,我认为是正确的
我做了这些改变
我使用Time::Piece
获取文件名的日期戳。它是一个核心模块,只需生成%d-%m-%Y
个日期戳即可。 DateTime
是非核心的,并且为了这么简单的目的而需要加载大量代码
顺便说一下,我使用ymd
格式代替dmy
。如果您希望按照自己编写代码的方式进行更改,则可以将其更改回来,但ymd
名称很有用,因为它们按日期顺序排序
我使用了来自File::Spec::Functions
的catdir
和catfile
,这是核心File::Spec
库的过程接口。它可以避免担心一个变量在结尾处是否有斜线而另一个变量在开头是否有斜线,并且可以使代码更清晰,因为它避免了所有那些令人讨厌的字符串连接
我已使用File::Path
中的make_path
来确保目标目录确实存在
由于要归档的文件的路径无论如何都存储在数组中,没有理由不使用create_archive
类方法一次性构建和保存文件
create_archive
的第二个参数是压缩方法。我已将其设置为零以请求无压缩和最大速度,但您可以通过传递COMPRESS_GZIP
或COMPRESS_BZIP
虽然模块的文档不鼓励它,但您也可以将此参数设置为1到9以指示gzip压缩级别。如果您要归档文本文件,那么我强烈建议您在此处使用1或2。传递COMPRESS_GZIP
会导致gzip压缩级别为9,这是迄今为止最慢的压缩级别,并且通常会导致*压缩比较低的*文件。值1通常会为您提供未压缩存档大小的三分之一的文件,而2可能会给您另外5%的减少。之后通常收益很少
我添加了一些日志消息,以提供信心并告知程序的进度。我还编写了一个小bytes
子程序,将文件大小转换为适当的1KB功率,使其更具可读性
我使用的是Windows路径,因为那是我碰巧坐在那里的桌子。由于使用File::Spec
,一旦你在路径和文件名设置在代码顶部+
无论你是否使用它,我希望你发现它很有用
use strict;
use warnings;
use Archive::Tar;
use File::Find qw/ find /;
use Time::Piece;
use File::Spec::Functions qw/ catfile catdir /;
use File::Path qw/ make_path /;
STDOUT->autoflush;
my $BACKUP_PATH = 'E:/Perl';
my $website_folder_name = 'website';
my $website_backup_name = 'website_backup';
print "Making list of files to archive\n";
my $source_dir = catdir($BACKUP_PATH, $website_folder_name);
my @filelist;
find( sub {
return unless -f;
push @filelist, $File::Find::name;
}, $source_dir);
printf "List complete - %d files to be archived\n", scalar @filelist;
my $tardir = catdir($BACKUP_PATH, $website_backup_name);
make_path($tardir, { verbose => 1 } );
my $date = localtime()->ymd;
my $tarfile = catfile($tardir, "$date-$website_backup_name.tar");
print qq{Writing archive to "$tarfile"\n};
my $success = Archive::Tar->create_archive($tarfile, 0, @filelist);
printf "Archive written successfully - %s\n", bytes(-s $tarfile) if $success;
sub bytes {
my ($size) = @_;
my @prefix = ( '', qw/ K M G T P E / );
my $pow = 0;
while ( $size >= 1024 ) {
$size /= 1024;
++$pow;
}
sprintf "%.0f%sB", $size, $prefix[$pow];
}
Making list of files to archive
List complete - 6602 files to be archived
Writing archive to "E:\Perl\website_backup\2016-01-07-website_backup.tar"
Archive written successfully - 7MB
答案 1 :(得分:1)
glob
(perldoc)不会递归到子目录中。您需要自己处理或使用File::Find
之类的模块:
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");