Lendo e escrevendo em arquivos

Vamos ver como podemos ler/escrever para um arquivo de texto com a ajuda de um simples programa p027readwrite.rb

 1 # p027readwrite.rb
 2 # Abrir e ler um arquivo de texto
 3 # Note que como é dado um bloco, o arquivo
 4 # é automaticamente fechado quando o bloco termina
 5 File.open('p014constructs.rb', 'r') do |f1|
 6   while line = f1.gets
 7     puts line
 8   end
 9 end
10 
11 # Cria um novo arquivo e escreve nele
12 File.open('test.rb', 'w') do |f2|
13   # use "\n" para duas linhas de texto
14   f2.puts "Criado por Satish\nGracas a Deus!"
15 end

O método File.open pode abrir o arquivo em modos diferentes como o ‘r’ (somente-leitura), que inicia no começo do arquivo; ‘r+’ Leitura/Escrita, começa no início do arquivo; ‘w’ Somente-escrita, trunca o arquivo existente para tamanho zero ou cria um novo arquivo para escrita. Cheque a documentação do Ruby para uma lista completa dos modos disponíveis. File.open abre um novo arquivo (File) se não existe nenhum bloco associado. Se o bloco opcional é dado, o arquivo será passado como argumento, e o arquivo será fechado automaticamente quando o bloco termina. Sempre feche um arquivo que você abriu. No caso de um arquivo aberto para escrita, isso é muito importante e pode até mesmo prevenir a perda de dados.

File implementa um método readlines (lê linhas) que lê um arquivo inteiro dentro de um array, linha por linha.

Ambos métodos de classe, open e readlines, pertencem a classe IO, cuja subclasse é File. Ainda não estudamos classes, objetos e herança mas, apenas para registro, estes dois métodos são herdados pela subclasse File da classe IO.

Varrendo Árvores de Diretórios

O módulo Find pode percorrer de maneira top-down (de cima para baixo) um conjunto de caminhos de arquivo, dados como argumento para o método find. Se o argumento for um diretório, então seu nome e o nome de todos seus arquivos e subdiretórios serão passados (no exemplo abaixo, isso seria a partir do diretório que você roda o programa).

 1 require 'find'
 2 Find.find('./') do |f|
 3   type = case
 4          when File.file?(f) then "F"
 5          when File.directory?(f) then "D"
 6          else "?"
 7          end
 8   puts "#{type}: #{f}"
 9 end

Falaremos sobre require em breve.

Acesso Aleatório

É bastante fácil acessar um arquivo aleatoriamente. Digamos que temos um arquivo texto (chamado hellousa.rb) cujo conteúdo é mostrado abaixo:

1 puts 'Ola EUA'

Agora precisamos mostrar o conteúdo do arquivo a partir da palavra EUA. Aqui está como – programa p028xrandom.rb:

 1 # p028xrandom.rb
 2 # Precisamos mostrar o conteúdo do arquivo a partir da palavra EUA
 3 f = File.new("hellousa.rb")
 4 
 5 # SEEK_CUR - Busca a partir do primeiro parâmetro inteiro mais a posição atual
 6 # SEEK_END - Busca a partir do primeiro parâmetro inteiro mais a posição final do stream
 7 #  (você provavelmente quer um valor negativo para o primeiro parâmetro inteiro)
 8 # SEEK_SET - Busca a partir da posição absoluta dada pelo primeiro parâmetro inteiro
 9 # :: é o operador de escopo - será explicado mais tarde
10 f.seek(10, IO::SEEK_SET)
11 print f.readline
12 f.close

A saída é:

1 >ruby p028xrandom.rb
2 EUA'
3 >Exit code: 0

O Ruby suporta a ideia de um apontador para um arquivo. O apontador indica a posição atual no arquivo. O método File.new abri o arquivo ‘hellousa.rb’ no modo somente leitura (modo padrão), retorna um novo objeto File e o ponteiro para o arquivo é posicionado no início do mesmo. No programa acima, a próxima instrução é f.seek(10, IO:SEEK_SET). O método seek da classe IO, move o ponteiro do arquivo para uma distância dada por um número inteiro (o primeiro parâmetro do método seek) no stream de acordo com o valor do segundo parâmetro no método seek.

IO::SEEK_CUR – Busca a partir do primeiro parâmetro inteiro mais a posição atual;
IO::SEEK_END – Busca a partir do primeiro parâmetro inteiro mais a posição final do stream (você provavelmente quer um valor negativo para o primeiro parâmetro inteiro);
IO::SEEK_SET – Busca a partir da posição absoluta dada pelo primeiro parâmetro inteiro.

Leia mais sobre o operador :: na seção sobre constantes.

Ruby permite a serialização de um objeto?

Uma das funcionalidades do Java é a capacidade de serializar objetos, o que permite que você armazene-os em qualquer lugar e então os reconstitua quando necessário. O Ruby chama esse tipo de serialização de marshaling (“preparação”). Salvar um objeto e alguns ou todos os seus componentes é feito usando o método Marshal.dump. Em um momento posterior você pode reconstituir o objeto usando Marshal.load. O Ruby usa marshaling para armazenar dados de sessão. Dirija-se ao tópico Serialização de Objetos para saber mais.

Sumário

Listei todos os pontos importantes que você precisa saber após ter completado os seguintes tópicos: Arrays, Intervalos, Símbolos, Hashes (Dicionários), Números aleatórios, Lendo/Escrevendo em arquivos de texto.

Logo do Guru-SP

Este material tem como base o tutorial do RubyLearning.com de Satish Talim e foi traduzido por membros do GURU-SP com a permissão do autor.

Ajude o RubyLearning participando em algum dos cursos pagos ou fazendo uma doação para o projeto

Voltar para o índice