[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