Perl Archive :: Zip resposta estranha

0

Isso realmente me confundiu: esse código funciona bem ...

$filename="name_of_file.pdf";

for ($x=0; $x<@pdf; $x++){
$file.=$pdf[$x];
}
$file=~s/\*ref\*/$new_aff/g;    # converts a variable within the PDF

use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new(); 
$now=time();
$save_zip=$now.".zip";
my $member = $zip->addString($file,$filename);
$member->desiredCompressionMethod( COMPRESSION_DEFLATED );
$member->desiredCompressionLevel( 9 );
die 'write error' unless $zip->writeToFileNamed($save_zip) == AZ_OK;

open (FILE, "<$save_zip");
flock(FILE,2);
binmode(FILE);
    while(<FILE>){
    $infile.=$_;
    }
flock(FILE,8);
close (FILE);

unlink($save_zip);
$filename=~s/\.pdf/\.zip/;


print "Content-type: application/zip\n";
print "Content-disposition: inline;filename=\"$filename\"\n\n";
print $infile;

O arquivo é lido e armazenado em @pdf. Em seguida, ele é convertido em um arquivo em vez de matriz. É então adicionado a um zip e salvo. É então lido novamente para imprimir na tela para abrir o diálogo de salvar. (OK, então codificar é um pouco "duvidoso", mas economiza confusão com streams etc que eu sei agora!)

Agora estou praticamente fazendo a mesma coisa, mas em vez de um único nome de arquivo, estou lendo um diretório e fazendo chamadas para uma sub rotina ...

opendir(PDF, "../data/viral/");
@pdfDir=readdir(PDF);
closedir(DIR);
@pdfDir=grep(!/^\./, @pdfDir);
@pdfDir=grep(!/\.txt/, @pdfDir);

use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new(); 
$now=time();
$save_zip=$now.".zip";

for ($x=0; $x<@pdfDir; $x++){
 &process_all;
 }
die 'write error' unless $zip->writeToFileNamed($save_zip) == AZ_OK;  # Write file out once loop finished

sub process_all{    # Processs all the PDF's
&open_pdf;          # Read in as BINMODE
    for ($z=0; $z<@pdf; $z++){
    $file.=$pdf[$z];
    }
$file=~s/\*ref\*/$new_aff/g;    # converts a variable within the PDF

my $member = $zip->addString($file,$pdfDir[$x]);
$member->desiredCompressionMethod( COMPRESSION_DEFLATED );
$member->desiredCompressionLevel( 9 );
$file="";   # Empty the file ready for next PDF
}

Mas ele reclama que "Não é possível chamar o método" addString "em um valor indefinido" E, no entanto, o nome do arquivo está correto e o PDF está sendo convertido em um arquivo, como mostrado se eu fizer uma impressão na tela.

Eu tentei $ filename = $ pdf [$ x] dentro do loop $ x e na rotina secundária. Ambos mostram o nome do arquivo correto, mas também não evitam o erro.

Provavelmente está me encarando - mas não consigo ver!

    
por Chris Brown 03.04.2015 / 19:21

1 resposta

0

Resolvido!

No topo do código onde eu abri o diretório, eu usei "opendir (PDF ..." mas no closedir eu tinha "closedir (DIR ..." que significava que o stream ainda estava aberto). quando fui abrir o arquivo, usei "open (PDF ..." e que já estava aberto, por isso não consegui ler os dados para armazenar no zip.

Ou pelo menos, isso fazia parte do problema. Ainda não parecia gostar de correr de uma sub rotina! No final, eu tive que usar:

use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
$zip = Archive::Zip->new(); 
$now=time();
$save_zip=$now.".zip";

for ($x=0; $x<@pdfDir; $x++){
$filename=$pdfDir[$x];
&open_pdf;
$file=~s/\*ref\*/$new_aff/g;
$member = $zip->addString($file,$filename);
$member->desiredCompressionMethod( COMPRESSION_DEFLATED );
$member->desiredCompressionLevel( 9 );
$file="";
}
die 'write error' unless $zip->writeToFileNamed($save_zip) == AZ_OK;

E a rotina aberta é agora:

open (PDF, "<....$filename");
while(<PDF>){
$file.=$_;
}
close(PDF);

Isso pode ajudar alguém que obtiver resultados igualmente estranhos!

    
por 04.04.2015 / 17:46

Tags