[Cascavel-pm] Ler partes do arquivo

Paulo paulo em odos.com.br
Domingo Janeiro 27 16:38:44 PST 2008


Patty Silva escreveu:
> Pessoal.. tenho um arquivo com aproximadamente 90 Mb..
> Fiz um programa que le os dados desse arquivo e busca certos blocos ..
> So que o arquivo eh muito grande... tem como eu ler parte por parte do 
> arquivo e processar minha logica??
> Ex: ler 10 Mb por vez.. e continuar lendo de 10 em 10
>
> estava pesquisando e percebi que se eu definir a variavel $/  eu 
> consigo..
> como irei fazer um loop sobre ela??
>
>
> Obrigada..
>


Sra. Patty, pelo que entendi você tem um arquivo grande (90MB) e quer 
quebra-lo em arquivos de (10MB) para poder processa-los. Se este 
processamento envolve delimitadores marcando INICIO e FIM de bloco, você 
terá que quebra-lo respeitando os blocos caso contrário a estrutura 
ficará corrompida. Já que terá que fazer isso porque não processa-lo 
linha a linha, simplificaria bastante.

Embora as informações fornecidas sejam escassas, por exemplo?

Precisa ser eficiente?

O arquivo é texto (quebrado em linhas)?

Os delimitadores de bloco são consistentes? ou seja, todo bloco é 
marcado por estes delimitadores e estes delimitadores são utilizados 
apenas para marcar os blocos.

O espaço em disco é limitado?

Vamos supor que os delimitadores de bloco sejam INICIO e FIM, e que 
estão espalhados pelas linhas. Suponhamos ainda que um bloco pode ou não 
estar em uma mesma linha e que você não tem problemas com espaço em 
disco e nem com eficiência.

Assim sendo:
A partir do arquivo de entrada podemos gerar um segundo arquivo, digamos 
pré-processado, que nos garanta que os delimitadore de início e fim de 
bloco estejam isolados em uma linha.

por exemplo assim:
#############################################################################
use strict;
use warnings;

open($fh_in,'<','Exemplo.txt') or die "$!";
open($fh_out,'>','Formatado.txt') or die "$!";
while my $line (<$fh_in>){
    $line =~ s/(INICIO|FIM)/\n$1\n/g;
    print $fh_out $line;
};
close($fh_in) or die "$!";
close($fh_out) or die "$!";
#############################################################################





Uma vez feito isso podemos tratar os blocos assim
#############################################################################
open($fh,'<','Formatado.txt') or die "$!";
my $bloco = '';
while my $line (<$fh>){
    next if(/^INICIO$/);
    if(/^FIM$/){
        processa_bloco(\$bloco);
        $bloco = '';
        next;
    };   
    $bloco .= $line;
};


sub processa_bloco{
    my $ref = shift;
    my $bloco = $$ref;
   
    ##########
    # Trate seus blocos aqui
    # ...
    ##########

};
#############################################################################

Não é eficiênte, está escrito de uma maneira criticável mas talvez
se encaixe melhor no seu problema.


OBSERVAÇÃO IMPORTANTE: Eu não testei este código, é quase certo que tem 
erro !!!  


Desejo-lhe sucesso,

Paulo




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