[Cascavel-pm] Nomes longos no windows

Luis Campos de Carvalho monsieur_champs em yahoo.com.br
Domingo Abril 10 05:07:18 PDT 2005


Er Galvão Abbott - PM Porto Alegre wrote:
> Primeiramente valeu pelas respostas. Como sempre bem informativas e 
> claras. Decidi usar o system com uma lista, como o Flávio recomendou, 
> mas agora pintou outra dúvida:

   Eu tenho sugestões sobre o seu uso de system(), para deixar seu 
código mais simples de ler. :-)

> Eu executo duas chamadas system, uma para criar o diretório ($dirs[$d]) 
> dentro do arquivo Zip e uma para criar o arquivo ($files[$f]) dentro do 
> diretório dentro do arquivo Zip.

   Também tenho sugestões quanto a isso.

> Acontece que o WinRAR reclama que não pode usar o arquivo Zip porque ele 
> já está sendo usado por outro processo. Eu entendo que cada chamada 
> system faz um fork que cria um processo, certo?

   Correto.

> Ou seja, antes de cada operação (tanto de inserção de diretório como de 
> inserção de arquivo) eu teria que verificar se o processo anterior já 
> terminou o trabalho, correto?

   Mais que apenas "terminou o trabalho", mas que o windows removeu o 
lock que ele coloca sobre o arquivo. Segundo a documentação, system() é 
uma chamada /blocking/, o que quer dizer que seu processo /espera/ pelo 
término do processo iniciado por system() antes de continuar.

   Isso quer dizer que não basta tratar sinais, mas deve haver aqui um 
/atraso/ para se certificar de que o windows efetivamente "liberou" o 
arquivo para acesso de outros processos. É uma das coisas mais 
esquisitas que eu conheço do sistema operacional: ele cria e remove 
/locks/ sobre os arquivos SEM nosso consentimento, SEMPRE que um 
processo abre, remove ou modifica arquivos... faz pensar sériamente em 
quem manda no meu processador...

> Alguém poderia me dar umas dicas? Eu sei que tenho que usar signals, mas 
> como nunca usei antes queria umas dicas de vocês. Notem como é feito o 
> processo todo:

   Galvão, eu achei seu processo como um todo muito poluído.
   Desta forma, usei algumas técnicas de /Perl Golf/ para lipar um pouco 
o código, otimizando para legibilidade (bom, talvez não *tão* *legível* 
assim, afinal...). Seguem as três versões da linha de tentativas que deu 
melhores resultados. Todas elas executam exatamente seu código, mas com 
muito menos toques e muito mais simples de entender.

__PERL__
##
##  Versao I
##
#! -*- perl -*-
use constant WINRAR => 'C:/arquivos de programas/winrar/winrar.exe';
our @opts = ( 'A', '-ibck', '-afzip', '-m5', 'C:/'.$compfile );

foreach my $dir ( @dirs ){
     system WINRAR, @opts, $dir;
     opendir DH, $dir
	or die 'Impossivel abrir o diretório '.$dir.': '.$!;
     my @files = grep { $_ ne '.' && $_ ne '..' } readdir DH;
     foreach my $file( @files ){
	system WINRAR, @opts, $dir.'/'.$file;
     }
     closedir DH
	or die 'Impossivel fechar o diretório '.$dir.': '.$!;
}
__END__

##
##  Versao II
##
#! -*- perl -*-
use constant WINRAR => 'C:/arquivos de programas/winrar/winrar.exe';
our @opts = ( 'A', '-ibck', '-afzip', '-m5', 'C:/'.$compfile );

map { system WINRAR, @opts, $_;
       opendir DH, $_
	  or die 'Impossivel abrir o diretório '.$_.': '.$!;
       my @files = grep { $_ ne '.' && $_ ne '..' } readdir DH;
       my $dir = $_;
       map { system WINRAR, @opts, $dir.'/'.$_; } @files;
       closedir DH
	  or die 'Impossivel fechar o diretório '.$dir.': '.$!;
   } @dirs;
__END__

##
## Versao III
##
#! -*- perl -*-
our @_ = ( 'C:/arquivos de programas/winrar/winrar.exe',
	   qw/ A -ibck -afzip -m5 /, 'C:/'.$compfile );

map { system @_, $_;
       opendir DH, $_
	  or die "$0: $!$/";
       my $dir = $_;
       map { system @_, $dir.'/'.$_; }
         grep { $_ ne '.' && $_ ne '..' }
           readdir DH;
       closedir DH
	  or die "$0: $!$/";
   } @dirs;
__END__

   Para terminar, a quarta versão traz a alteração que você precisa para 
se assegurar de que o windows teve tempo de levantar aquele /lock/ 
não-autorizado sobre o seu arquivo:

__PERL__
##
## Versao IV
##
#! -*- perl -*-
use constant DELAY => 5; # você precisa ajustar este
                          # tempo para algum valor
                          # interessante...
our @_ = ( 'C:/arquivos de programas/winrar/winrar.exe',
	   qw/ A -ibck -afzip -m5 /, 'C:/'.$compfile );

map { system @_, $_;
       sleep DELAY;
       opendir DH, $_
	  or die "$0: $!$/";
       my $dir = $_;
       map { system @_, $dir.'/'.$_;
             sleep DELAY;
           }
         grep { $_ ne '.' && $_ ne '..' }
           readdir DH;
       closedir DH
	  or die "$0: $!$/";
   } @dirs;
__END__

   Espero que isso ajude em alguma coisa.
   Putamplexos!
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  Luis Campos de Carvalho is BSc in Comp Science,
  PerlMonk [SiteDocClan], Sao Paulo PM Leader,
  Unix Sys Admin && Certified Oracle DBA
  http://br.geocities.com/monsieur_champs/
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



Mais detalhes sobre a lista de discussão Cascavel-pm