使用Perl将目录及其文件和子目录添加到zip存档

时间:2015-06-27 05:47:00

标签: perl

这是文件夹结构

9781471839108_epub
    - 9781471839108_epub_ncx_r1.ncx
    - 9781471839108_epub_opf_r1.opf
    - mimetype
    meta-inf
        - container.xml
    oebps
        - ack.htm
        - ch01.htm
        audio
            - 1.mp3
        images
            - 1-1.jpg

当我想将文件放入二级文件夹(meta-infoebps)时,所有文件都放在主文件夹中

如何将文件放在各自的文件夹中 在meta-inf文件夹中,我想放置container.xml文件

以下是由我完成的编码

use warnings;
use strict;

use Cwd;
my $dir = getcwd;

use Archive::Zip;
use Archive::Zip qw( :ERROR_CODES );
use File::Basename 'basename';

my $zip         = Archive::Zip->new();
my $isbn_folder = "0";

opendir( min_dir, $dir ) or die "Cannot open $dir: $!";

foreach my $min_file ( readdir min_dir ) {
    if ( -d $min_file ) {
        $isbn_folder = $min_file;
    }
}
closedir min_dir;

my $isbn_folder_path = "$dir/$isbn_folder";
opendir( isbn_dir, $isbn_folder_path ) or die "Cannot open $dir: $!";
my @isbn_files = readdir( isbn_dir );
closedir isbn_dir;

foreach my $isbn_file ( @isbn_files ) {

    if ( -f "$isbn_folder_path/$isbn_file" ) {

        my @member = $isbn_file;

        foreach my $member ( @member ) {
            my $mine_file_path_add = "$isbn_folder_path/$member";
            my $member             = basename $mine_file_path_add;
            $zip->addFile( $mine_file_path_add, $member )
                or die 'unable to add file to archive';
        }
    }

    if ( -d "$isbn_folder_path/$isbn_file" ) {

        my @isbn_folder = $isbn_file;

        foreach my $isbn_folder ( @isbn_folder ) {

            if ( $isbn_folder =~ m/([0-9a-zA-Z])/ ) {

                my @isbn_folder1 = $isbn_folder;

                foreach my $isbn_folder1 ( @isbn_folder1 ) {

                    my $mine_file_path_add = "$isbn_folder_path/$isbn_folder1";
                    my $member             = basename $mine_file_path_add;

                    $zip->addDirectory( '$mine_file_path_add/', $member )
                        or die 'unable to add file to archive';

#__________I have problem to put this file on there respective dir______________

                    opendir( oebps_dir, $mine_file_path_add )
                        or die "Cannot open $dir: $!";
                    my @isbn_folder = readdir( oebps_dir );
                    closedir oebps_dir;

                    foreach my $isbn_folder ( @isbn_folder ) {

                        if ( -f "$mine_file_path_add/$isbn_folder" ) {

                            my @member = $isbn_folder;

                            foreach my $member ( @member ) {
                                my $mine_file_path_add =
                                    "$mine_file_path_add/$member";
                                my $member = basename $mine_file_path_add;
                                $zip->addFile( $mine_file_path_add, $member )
                                    or die 'unable to add file to archive';
                            }
                        }
                    }

#____________________________________
                }
            }
        }
    }
}

unless ( $zip->writeToFileNamed( "d:/perl/Tool/Test/making_epub/temp.zip" ) ==
    AZ_OK ) {
    die "whoops!";
}

1 个答案:

答案 0 :(得分:1)

主要问题是您专门使用basename修剪了您存储的每个文件或目录的路径信息。如果您保留完整路径,则会反映zip存档中的磁盘目录结构

也无需自行遍历文件路径,因为Archive::Zip方法addTreeaddTreeMatching将为您执行此操作

您还没有解释您正在尝试做什么,但是从您的Perl代码看起来您​​只想将整个目录结构存储在zip文件中。那里有一个测试

if ( $isbn_folder =~ m/([0-9a-zA-Z])/ )

我认为只是删除...伪目录

您选择存储的目录是当前目录的 last 子目录,您可以使用

找到该目录。
my $base_folder = ( grep -d, glob '*')[-1];

您可以通过调用addTree将其保存到zip存档,如下所示

我使用了select参数,您可以使用该参数选择将哪些文件和目录添加到存档中。在这种情况下,它总是返回 true ,因此所有内容都被归档,但它可以作为存储文件的有用日志

use strict;
use warnings;
use 5.010;

use Archive::Zip qw/ :ERROR_CODES :MISC_CONSTANTS /;

use constant ZIP_FILE => 'D:\perl\Tool\Test\making_epub\temp.zip';

STDOUT->autoflush;

my $base_folder = ( grep -d, glob '*')[-1];

my $zip = Archive::Zip->new;

$zip->addTree({
  root => $base_folder,
  select => sub {
    say "Storing $_";
    1;
  },
  compressionLevel = DEFLATING_COMPRESSION_NORMAL,
});

$zip->writeToFileNamed(ZIP_FILE) == AZ_OK or die "Failed to save zip file: $!";

say "\nZip file written";