Abrindo e Lendo Arquivos de Texto
Nesta parte do tutorial Perl nós iremos ver como ler arquivos de texto em Perl.
Por enquanto iremos focar apenas nos arquivos de texto.
Exceções
Caso 1: Lance uma exceção caso não consiga abrir o arquivo:
use strict; use warnings; my $filename = 'data.txt'; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Não foi possível abrir o arquivo '$filename' $!"; while (my $row = <$fh>) { chomp $row; print "$row\n"; }
Alerta ou nenhum aviso
Caso 2: Receber apenas um aviso caso o arquivo não possa ser aberto, mas mantenha o código executando:
use strict; use warnings; my $filename = 'data.txt'; if (open(my $fh, '<:encoding(UTF-8)', $filename)) { while (my $row = <$fh>) { chomp $row; print "$row\n"; } } else { warn "Não foi possível abrir o arquivo '$filename' $!"; }
Explicações
Vamos ver as explicações dos casos:
Primeiramente, utilizando um editor de textos, crie um arquivo chamado 'data.txt' e adicione algumas linhas a ele:
Primeira linha Segunda linha Terceira linha
Abrir um arquivo para leitura é muito parecido com o que fizemos quando vimos como abrir um arquivo para escrita, porém ao invés de utilizar o sinal "maior do que" (>), nós iremos utilizar o o sinal "menor do que" (<).
Desta vez também estamos definindo a codificação para UTF-9. Masn na maioria dos casos, você irá apenas encontrar o sinal "menor do que".
use strict; use warnings; my $filename = 'data.txt'; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Não foi possível abrir o arquivo '$filename' $!"; my $row = <$fh>; print "$row\n"; print "pronto\n";
Após ter o filehandle nós podemos então ler a partir dele, utilizando o mesmo operador de leitura de linhas, o readline, para leitura do teclado (STDIN). Assim conseguiremos ler a primeira linha do arquivo. Em seguida nós imprimimos o conteúdo da variável $row e depois "pronto" apenas para que fique evidente que chegamos até o final do nosso exemplo.
Se você executar o script acima verá o seguinte ser impresso:
Primeira linha prontoPor que existe uma linha vazia antes do "pronto", você pode se perguntar.
Isso ocorre porque o operador readline lê a linha inteira, incluíndo o caractere especial de nova linha. Quando nós utilizamos a função print, acabamos incluíndo um segundo caractere de nova linha.
Da mesma forma que ocorre quando lemos algo a partir do STDIN, nós normalmente não precisamos o caractere final indicando uma nova linha, então podemos usar a função chomp() para removê-lo.
Lendo mais de uma linha
Agora que já sabemos como ler uma linha, podemos segui a diante e colocar o readline dentro de um laço while.
use strict; use warnings; my $filename = $0; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Não foi possível abrir o arquivo '$filename' $!"; while (my $row = <$fh>) { chomp $row; print "$row\n"; } print "pronto\n";
Toda vez que atingimos a condicional do laço while, primeiro será executado my $row = <$fh>, a parte que irá ler a próxima linha do arquivo. Se existir alguma coisa nessa linha, a condicional será avaliada como VERDADEIRA. Até mesmo linhas vazias possuem caracteres especiais de nova linha, isso significa que ao ler essas linhas a variável $row irá conter o \n que irá ser avaliado como VERDADEIRO em contexto booleano.
Após ler a última, na próxima iteração do laço o operador readline (<$fh>) irá retornar undef que então é avaliado como FALSO. Sendo assim o laço while termina.
Casos extremos
Em determinados casos, existe a possibilidade do arquivo possuir um 0 em sua última linha. O código acima, iria neste caso, avaliar a última linha como FALSO e o laço não seria mais executado. Felizmente, o Perl acaba trapaceando nessa situação. Neste caso específico (ler uma linha de um arquivo dentro de um laço while), o perl atua como se você tivesse escrito while (defined my $row = <$fh>) { fazendo com que até mesmo essas linhas sejam executadas corretamente.
Abrindo o arquivo sem matar o script
A forma descrita acima de abrir arquivos é utilizada em scripts Perl onde você deve obrigatoriamente ter um arquivo para ser lido. Por exemplo quando o objetivo do código é parsear aquele arquivo.
Mas e se for um arquivo de configuração opcional? Se você conseguir ler o arquivo então você altera seu conteúdo, caso não consiga utilizará os valores padrões.
Neste caso a segunda solução apresentada acima pode ser a melhor forma de escrever o seu código.
if (open(my $fh, '<:encoding(UTF-8)', $filename)) { while (my $row = <$fh>) { chomp $row; print "$row\n"; } } else { warn "Não foi possível abrir o arquivo '$filename' $!"; }
Neste caso avaliamos o valor de retorno da função open. Se for VERDADEIRO, nós lemos o seu conteúdo.
Se falhar nós apenas recebemos um aviso utilizando a função warn mas sem lançar uma exceção, nós não precisamos nem mesmo incluir a parte do else:
if (open(my $fh, '<:encoding(UTF-8)', $filename)) { while (my $row = <$fh>) { chomp $row; print "$row\n"; } }

Published on 2013-04-25