Carregando
Todos os artigos
Programação 19 min de leitura

Entrada e Saída de Arquivos em Ruby: Um Guia Visual e Prático

Aprenda entrada e saída de arquivos em Ruby de forma visual: três jeitos de ler um arquivo (e quanta memória cada um usa), arquivos que não existem, modos de arquivo, escrever e acrescentar, salvar em JSON, pastas, quebras de linha e exercícios com respostas.

nbkhope
Nesta página

Variáveis são esquecidas: no instante em que o seu programa termina, tudo o que estava nelas some. Para guardar um recorde, uma lista de tarefas, um diário ou um arquivo de configurações para a próxima vez, o programa precisa escrever num arquivo. E, para usar dados que vieram de outro lugar, como uma planilha exportada, um log ou um documento de texto, ele precisa ler um.

Isso é entrada e saída de arquivos (em inglês, file I/O, de input/output), e o Ruby deixa tudo bem fácil. Neste guia você vai ler um arquivo de três jeitos diferentes (e ver quanta memória cada um realmente usa), lidar com arquivos que não existem, escrever e acrescentar, salvar dados de jogo em JSON, organizar pastas e descobrir uma surpresa do Windows com as quebras de linha. Exercícios com respostas fecham o artigo.

A visão geral

E/S de arquivos: o seu programa conversa com um arquivo no disco. As variáveis do seu programa Ruby vivem na memória e somem quando o programa termina; um arquivo como arquivo.txt fica no disco e continua lá depois que o programa termina. Ler, ou entrada, traz dados do arquivo para o programa; escrever, ou saída, manda dados do programa para o arquivo. Todo trabalho com arquivos tem três passos: abrir, com File.open ou File.foreach; ler ou escrever, linha por linha ou tudo de uma vez; e fechar, que um bloco faz por você. E/S quer dizer entrada/saída

Todo trabalho com arquivos segue os mesmos três passos: abrir o arquivo, ler ou escrever e depois fechar. Como você vai ver, o Ruby pode abrir e fechar por você.

Todos os exemplos abaixo usam este arquivinho, arquivo.txt, na mesma pasta do script Ruby:

Este é um arquivo de exemplo
Com algum conteúdo dentro
Esta é a última linha :)

As execuções de exemplo vêm do Ruby 3.3.

Lendo um arquivo: três jeitos

Três jeitos de ler o mesmo arquivo. File.read(nome) devolve uma String grande, com o arquivo inteiro na memória de uma vez. File.readlines(nome) devolve um Array de linhas, com o arquivo inteiro na memória, em linhas. File.foreach(nome) com um bloco entrega uma linha por vez, e só a linha atual fica na memória, como itens numa esteira

1. File.read: tudo de uma vez

conteudo = File.read("arquivo.txt")
puts conteudo
puts "Foram #{conteudo.length} caracteres"
1Este é um arquivo de exemplo
2Com algum conteúdo dentro
3Esta é a última linha :)
4Foram 80 caracteres

Simples e prático para arquivos pequenos, como configurações ou modelos de texto.

2. File.readlines: um array de linhas

linhas = File.readlines("arquivo.txt", chomp: true)
p linhas
puts "O arquivo tem #{linhas.size} linhas; a última é: #{linhas.last}"
["Este é um arquivo de exemplo", "Com algum conteúdo dentro", "Esta é a última linha :)"]
O arquivo tem 3 linhas; a última é: Esta é a última linha :)

Ótimo quando você precisa das linhas como uma lista: para contá-las, ordená-las ou sortear uma. O chomp: true tira a quebra de linha do fim de cada uma.

3. File.foreach: uma linha por vez

File.foreach("arquivo.txt").with_index(1) do |linha, numero_da_linha|
  puts "#{numero_da_linha}: #{linha.chomp}"
end
1: Este é um arquivo de exemplo
2: Com algum conteúdo dentro
3: Esta é a última linha :)

O foreach entrega uma linha ao seu bloco, espera você terminar com ela e só então lê a próxima. O .with_index(1) numera as linhas a partir do 1.

Sobre aquela quebra de linha: chomp

Cada linha vem com o seu caractere de quebra de linha, \n, ainda grudado. O p mostra isso:

1File.foreach("arquivo.txt") do |linha|
2  p linha
3end
4p "Com algum conteúdo dentro\n".chomp
1"Este é um arquivo de exemplo\n"
2"Com algum conteúdo dentro\n"
3"Esta é a última linha :)\n"
4"Com algum conteúdo dentro"

O chomp corta fora. O puts não se importa, porque só acrescenta uma quebra de linha quando o texto ainda não termina com uma. Mas quando você compara uma linha com alguma coisa (linha == "olá") ou junta linhas, um \n esquecido causa bugs confusos.

Qual usar? Vamos medir

Os três leem o mesmo arquivo, então faz diferença qual você escolhe? Testamos com um arquivo de log grande: 146 MB, 2 milhões de linhas, contando as linhas que têm ERROR:

Lendo um arquivo de log de 146 MB: quanta memória? Contando as linhas com ERROR entre 2 milhões de linhas, medido para este artigo com Ruby 3.3.2 no Windows, pico de memória de um processo novo, mediana de 3 execuções. O Ruby sem fazer nada usa 20,8 MB. File.foreach, uma linha por vez: 21,8 MB e 0,61 segundo. File.read, uma String grande: 299,8 MB e 0,47 segundo. File.readlines, um array de 2 milhões de strings: 414,4 MB e 1,26 segundo. O foreach usou pouco mais memória que um programa Ruby vazio, não importa o tamanho do arquivo. O File.read foi um pouco mais rápido aqui, mas um arquivo maior que a sua memória simplesmente não caberia

O File.foreach usou só 1 MB a mais que um programa Ruby que não faz nada. O File.readlines precisou de mais de 390 MB extras, porque monta 2 milhões de strings separadas de uma vez. Veja como o programa da medição contou os erros de cada jeito:

File.read(nome_do_arquivo).each_line.count { |linha| linha.include?("ERROR") }
File.readlines(nome_do_arquivo).count { |linha| linha.include?("ERROR") }
File.foreach(nome_do_arquivo) { |linha| quantidade_de_erros += 1 if linha.include?("ERROR") }

Quando o arquivo não existe

E se o arquivo não existir? O Ruby para com um erro:

File.foreach("nao_existe.txt") do |linha|
  puts linha
end
faltando.rb:1:in `foreach': No such file or directory @ rb_sysopen - nao_existe.txt (Errno::ENOENT)
	from faltando.rb:1:in `<main>'

Errno::ENOENT é o nome do erro: "Error, NO such ENTry" ("não existe essa entrada"). Há dois bons jeitos de lidar com isso:

O arquivo pode não estar lá: dois jeitos de lidar. Olhe antes de pular: if File.exist?(nome), lê com File.foreach, senão imprime Arquivo não existe. Simples e legível para scripts do dia a dia. Tente e trate o erro: begin, File.foreach, rescue Errno::ENOENT => erro, puts erro.message, end. Também cobre o arquivo sumir entre a verificação e a leitura. Trate o erro específico, Errno::ENOENT, que quer dizer arquivo não existe, não Exception, para os bugs de verdade continuarem aparecendo

Opção 1: verifique antes com File.exist?

1nome_do_arquivo = "exemplo.txt"
2
3if File.exist?(nome_do_arquivo)
4  File.foreach(nome_do_arquivo) do |linha|
5    puts linha.chomp
6  end
7else
8  puts "Desculpe, #{nome_do_arquivo} não existe."
9end
Desculpe, exemplo.txt não existe.

Opção 2: tente e trate o erro

1begin
2  File.foreach("nao_existe.txt") do |linha|
3    puts linha
4  end
5rescue Errno::ENOENT => erro
6  puts "Ops, esse arquivo não está aqui!"
7  puts erro.message
8  puts "Vamos seguir sem ele."
9end
Ops, esse arquivo não está aqui!
No such file or directory @ rb_sysopen - nao_existe.txt
Vamos seguir sem ele.

O código que você tenta rodar fica entre o begin e o rescue. Se aquele erro específico acontecer, o Ruby pula para a parte do rescue em vez de travar, e o erro.message descreve o que deu errado.

Escrevendo um arquivo

Para escrever, abra o arquivo no modo de escrita, "w", e use puts nele, como se estivesse imprimindo na tela:

1File.open("novo.txt", "w") do |arquivo|
2  arquivo.puts "Olá, pessoal!"
3  arquivo.puts "Este vai ser um arquivo novinho!"
4  arquivo.puts "Só mais uma última linha"
5end
6
7puts File.read("novo.txt")
Olá, pessoal!
Este vai ser um arquivo novinho!
Só mais uma última linha

Dentro do bloco, arquivo é a sua conexão com o arquivo. Quando o bloco termina, o Ruby fecha o arquivo para você.

puts, print, write e <<

1File.open("saida.txt", "w") do |arquivo|
2  arquivo.puts "o puts acrescenta uma quebra de linha"
3  arquivo.print "o print não"
4  arquivo.print " (viu?)\n"
5  arquivo.write "o write funciona como o print, "
6  arquivo << "e o << pode ser encadeado" << "!\n"
7end
8puts File.read("saida.txt")
o puts acrescenta uma quebra de linha
o print não (viu?)
o write funciona como o print, e o << pode ser encadeado!

Atalhos de uma linha

Para tarefas rápidas, o File.write abre, escreve e fecha de uma vez só. Acrescente mode: "a" para acrescentar em vez de sobrescrever:

File.write("compras.txt", "leite\novos\n")
File.write("compras.txt", "pão\n", mode: "a")
puts File.read("compras.txt")
leite
ovos
pão

Modos de arquivo: cuidado com o "w"

O segundo argumento do File.open é o modo. Ele decide se você pode ler, escrever ou os dois e, o mais importante, o que acontece com o que já está no arquivo:

Modos de arquivo: o que cada um faz? "r" só lê; arquivo que não existe dá erro; o conteúdo existente é mantido. "w" só escreve; um arquivo que não existe é criado; o conteúdo existente é APAGADO; escreve a partir do início. "a" só escreve; um arquivo que não existe é criado; o conteúdo é mantido; escreve a partir do fim. "r+" lê e escreve; arquivo que não existe dá erro; o conteúdo é mantido; escreve a partir do início. "w+" lê e escreve; um arquivo que não existe é criado; o conteúdo é APAGADO. "a+" lê e escreve; um arquivo que não existe é criado; o conteúdo é mantido; escreve a partir do fim. O "r" é o padrão. Acrescente "b", como "rb" ou "wb", para arquivos binários, como imagens, para o Ruby não mexer nas quebras de linha

Os dois que você mais vai usar são "w" (começar um arquivo do zero) e "a" (acrescentar no fim). Trocar um pelo outro é o jeito clássico de perder dados:

1File.write("diario.txt", "Segunda: aprendi Ruby\n")
2
3File.open("diario.txt", "a") { |arquivo| arquivo.puts "Terça: aprendi E/S de arquivos" }
4puts "Depois de acrescentar com \"a\":"
5puts File.read("diario.txt")
6
7File.open("diario.txt", "w") { |arquivo| arquivo.puts "Quarta: ops" }
8puts "Depois de abrir com \"w\":"
9puts File.read("diario.txt")
1Depois de acrescentar com "a":
2Segunda: aprendi Ruby
3Terça: aprendi E/S de arquivos
4Depois de abrir com "w":
5Quarta: ops
A diferença entre "a" e "w". O diario.txt começa com uma linha, Segunda: aprendi Ruby. Abrir com "a" e escrever acrescenta Terça: aprendi E/S de arquivos no fim, mantendo a segunda-feira. Abrir com "w" deixa só Quarta: ops: tudo o que havia antes sumiu

Deixe um bloco fechar o arquivo por você

Um arquivo aberto usa recursos, e o que você escreve pode ficar esperando num buffer até o arquivo ser fechado. Com um bloco, o Ruby fecha o arquivo sozinho quando o bloco termina, mesmo que aconteça um erro dentro dele:

Deixe um bloco fechar o arquivo por você. Com um bloco, File.open com do |arquivo|, arquivo.puts e end: o arquivo é fechado no end, mesmo com erro. Sem um bloco, arquivo = File.open, arquivo.puts e arquivo.close, que é fácil de esquecer: esqueça o close, ou trave antes dele, e o arquivo fica aberto, e as escritas podem nem ter chegado ao disco

Sem um bloco, fechar é responsabilidade sua:

1arquivo = File.open("manual.txt", "w")
2arquivo.puts "Lembre de me fechar!"
3arquivo.close
4puts "Fechado? #{arquivo.closed?}"
5puts File.read("manual.txt")
Fechado? true
Lembre de me fechar!

Funciona, mas se algo der errado entre o open e o close, o arquivo fica aberto. Prefira a forma com bloco.

Uma tarefa de verdade: ler dados e escrever um relatório

Este é o tipo de script pequeno para o qual a E/S de arquivos é perfeita. O notas.txt tem um aluno por linha:

1Ana,90
2Bruno,85
3Carla,77
4Diego,92
5Eva,68

O script lê o arquivo, calcula a média e o melhor aluno, e escreve um relatório:

1total = 0
2melhor_nome = nil
3melhor_nota = -1
4
5File.foreach("notas.txt") do |linha|
6  nome, texto_da_nota = linha.chomp.split(",")
7  nota = texto_da_nota.to_i
8  total += nota
9  if nota > melhor_nota
10    melhor_nota = nota
11    melhor_nome = nome
12  end
13end
14
15quantidade_de_alunos = File.readlines("notas.txt").size
16media = total.to_f / quantidade_de_alunos
17
18File.open("relatorio.txt", "w") do |relatorio|
19  relatorio.puts "Alunos:  #{quantidade_de_alunos}"
20  relatorio.puts "Média:   #{media.round(1)}"
21  relatorio.puts "Melhor:  #{melhor_nome} (#{melhor_nota})"
22end
23
24puts File.read("relatorio.txt")
Alunos:  5
Média:   82.4
Melhor:  Diego (92)

Salvando dados com JSON

Texto simples é ótimo para linhas de palavras. Para dados estruturados, como um hash de recordes, as configurações de um app ou o arquivo de save de um jogo, use JSON, um formato de texto que quase toda linguagem de programação consegue ler:

Salvando e carregando dados com JSON. Um Hash do Ruby como { "Ana" => 1200, "Bruno" => 950 } vira texto JSON com JSON.pretty_generate e é salvo em recordes.json no disco com File.write. File.read mais JSON.parse o transforma de volta num Hash do Ruby. O JSON transforma dados do Ruby em texto simples que continua existindo depois que o programa termina, e que outras linguagens também conseguem ler
1require "json"
2
3recordes = { "Ana" => 1200, "Bruno" => 950, "Carla" => 1430 }
4File.write("recordes.json", JSON.pretty_generate(recordes))
5puts File.read("recordes.json")
6
7carregados = JSON.parse(File.read("recordes.json"))
8campea, pontos = carregados.max_by { |nome, pontuacao| pontuacao }
9puts "Campeã: #{campea} com #{pontos} pontos"
1{
2  "Ana": 1200,
3  "Bruno": 950,
4  "Carla": 1430
5}
6Campeã: Carla com 1430 pontos

Pastas e caminhos

As classes Dir e File do Ruby, mais a biblioteca fileutils, cuidam de pastas e nomes de arquivos:

1require "fileutils"
2
3FileUtils.mkdir_p("anotacoes/2026")
4File.write(File.join("anotacoes", "2026", "janeiro.txt"), "Feliz ano novo!\n")
5File.write(File.join("anotacoes", "2026", "fevereiro.txt"), "Mês curto.\n")
6
7Dir.glob("anotacoes/**/*.txt").sort.each do |caminho|
8  puts "#{caminho}  (nome: #{File.basename(caminho, '.txt')}, extensão: #{File.extname(caminho)})"
9end
anotacoes/2026/fevereiro.txt  (nome: fevereiro, extensão: .txt)
anotacoes/2026/janeiro.txt  (nome: janeiro, extensão: .txt)
  • FileUtils.mkdir_p cria uma pasta, incluindo as pastas-mãe que faltarem.
  • File.join monta um caminho com o separador certo.
  • Dir.glob("anotacoes/**/*.txt") acha todos os arquivos .txt dentro de anotacoes, em qualquer subpasta.
  • File.basename e File.extname desmontam um caminho.

Duas coisas que surpreendem

Acentos e emoji: caracteres vs. bytes

O Ruby lê e escreve texto em UTF-8, então acentos e emoji funcionam sem problema. Mas um caractere nem sempre é um byte:

1File.write("saudacoes.txt", "Olá, café com pão!\n")
2texto = File.read("saudacoes.txt")
3puts texto
4puts "Caracteres: #{texto.chomp.length}, bytes: #{texto.chomp.bytesize}"
5puts "Codificação: #{texto.encoding}"
Olá, café com pão!
Caracteres: 18, bytes: 21
Codificação: UTF-8

á, é e ã ocupam 2 bytes cada em UTF-8, e é por isso que 18 caracteres enchem 21 bytes.

Quebras de linha no Windows

Escreva as mesmas duas linhas em modo texto e em modo binário no Windows, e os arquivos saem com tamanhos diferentes:

1File.open("modo_texto.txt", "w") { |arquivo| arquivo.puts "um"; arquivo.puts "dois" }
2File.open("modo_binario.txt", "wb") { |arquivo| arquivo.puts "um"; arquivo.puts "dois" }
3puts "Modo texto:   #{File.size('modo_texto.txt')} bytes"
4puts "Modo binário: #{File.size('modo_binario.txt')} bytes"
5p File.binread("modo_texto.txt")
6p File.read("modo_texto.txt")

Execução de exemplo no Windows:

1Modo texto:   10 bytes
2Modo binário: 8 bytes
3"um\r\ndois\r\n"
4"um\ndois\n"
Duas linhas, dois tamanhos: quebras de linha no Windows. No modo texto, "w", no Windows os bytes são u, m, barra r, barra n, d, o, i, s, barra r, barra n: 10 bytes. No modo binário, "wb", ou no macOS e no Linux, são u, m, barra n, d, o, i, s, barra n: 8 bytes. O Windows termina as linhas com dois caracteres, barra r barra n. No modo texto, o Ruby acrescenta o barra r ao escrever e o tira ao ler, então o seu código vê o mesmo barra n em todo lugar

O Windows tradicionalmente termina as linhas com dois caracteres, \r\n. No modo texto, o Ruby traduz em silêncio, então o seu código sempre vê um \n simples. No macOS e no Linux, os dois arquivos têm 8 bytes. Use o modo binário ("rb", "wb") para imagens, PDFs e outros arquivos que não são texto, para o Ruby não "traduzir" bytes que nem são quebras de linha.

Hora de praticar

Crie o arquivo.txt com as três linhas do começo deste artigo e tente fazer estes antes de espiar as respostas.

Exercício 1: Adivinhe o conteúdo (aquecimento). Depois de rodar isto, o que fica em numeros.txt?

File.write("numeros.txt", "1\n")
File.write("numeros.txt", "2\n")
File.write("numeros.txt", "3\n", mode: "a")

Exercício 2: Contador de palavras. Conte as linhas, as palavras e os caracteres do arquivo.txt, como faz o comando wc.

Exercício 3: Busca. Imprima cada linha do arquivo.txt que contenha a palavra linha, com o número dela.

Exercício 4: Diário. Escreva um método acrescenta_entrada(data, texto) que coloque uma linha como [2026-10-24] Comecei a aprender E/S de arquivos no diario.txt sem apagar as entradas anteriores.

Exercício 5: Em voz alta. Leia o arquivo.txt e escreva uma cópia em MAIÚSCULAS no gritando.txt, linha por linha.

Exercício 6: Tabela de recordes (desafio). Guarde os 3 melhores recordes em recordes.json. Escreva salva_recorde(nome, pontos), que carrega a lista (ou começa vazia se ainda não houver arquivo), acrescenta o novo recorde, mantém os 3 melhores e salva. Depois acrescente Ana 1200, Bruno 950, Carla 1430 e Diego 800, e imprima a tabela.

Quiz rápido

  1. Qual é a diferença entre os modos "w" e "a"?
  2. Qual método de leitura mantém o uso de memória estável num arquivo enorme?
  3. Por que usar rescue Errno::ENOENT em vez de rescue Exception?
  4. O que o chomp tira?
  5. Por que o File.open com bloco é mais seguro do que chamar o close você mesmo?

Respostas

Exercício 1: O segundo File.write substituiu o 1 (o modo de escrita começa do zero), e o terceiro acrescentou:

1File.write("numeros.txt", "1\n")
2File.write("numeros.txt", "2\n")
3File.write("numeros.txt", "3\n", mode: "a")
4print File.read("numeros.txt")
2
3

Exercício 2: O split sem argumentos divide em qualquer espaço em branco, e isso dá as palavras:

1quantidade_de_linhas = 0
2quantidade_de_palavras = 0
3quantidade_de_caracteres = 0
4
5File.foreach("arquivo.txt") do |linha|
6  quantidade_de_linhas += 1
7  quantidade_de_palavras += linha.split.size
8  quantidade_de_caracteres += linha.length
9end
10
11puts "Linhas: #{quantidade_de_linhas}, palavras: #{quantidade_de_palavras}, caracteres: #{quantidade_de_caracteres}"
Linhas: 3, palavras: 16, caracteres: 80

Exercício 3:

1palavra_procurada = "linha"
2
3File.foreach("arquivo.txt").with_index(1) do |linha, numero_da_linha|
4  puts "#{numero_da_linha}: #{linha}" if linha.include?(palavra_procurada)
5end
3: Esta é a última linha :)

Só a linha 3 bate: nenhuma das outras contém "linha".

Exercício 4: O modo de acrescentar, "a", mantém o que já está lá:

1def acrescenta_entrada(data, texto)
2  File.open("diario.txt", "a") do |diario|
3    diario.puts "[#{data}] #{texto}"
4  end
5end
6
7acrescenta_entrada("2026-10-24", "Comecei a aprender E/S de arquivos")
8acrescenta_entrada("2026-10-25", "Escrevi o meu primeiro arquivo de log")
9puts File.read("diario.txt")
[2026-10-24] Comecei a aprender E/S de arquivos
[2026-10-25] Escrevi o meu primeiro arquivo de log

Exercício 5: Abra a saída uma vez e faça a entrada passar por ela:

1File.open("gritando.txt", "w") do |saida|
2  File.foreach("arquivo.txt") do |linha|
3    saida.puts linha.chomp.upcase
4  end
5end
6
7puts File.read("gritando.txt")
ESTE É UM ARQUIVO DE EXEMPLO
COM ALGUM CONTEÚDO DENTRO
ESTA É A ÚLTIMA LINHA :)

Repare que o upcase do Ruby também cuida das letras acentuadas.

Exercício 6: Uma cláusula de guarda cuida da primeira execução, quando ainda não existe arquivo:

1require "json"
2
3ARQUIVO_DE_RECORDES = "recordes.json"
4
5def carrega_recordes
6  return [] unless File.exist?(ARQUIVO_DE_RECORDES)
7
8  JSON.parse(File.read(ARQUIVO_DE_RECORDES))
9end
10
11def salva_recorde(nome, pontos)
12  recordes = carrega_recordes
13  recordes << { "nome" => nome, "pontos" => pontos }
14  tres_melhores = recordes.sort_by { |recorde| -recorde["pontos"] }.first(3)
15  File.write(ARQUIVO_DE_RECORDES, JSON.pretty_generate(tres_melhores))
16end
17
18salva_recorde("Ana", 1200)
19salva_recorde("Bruno", 950)
20salva_recorde("Carla", 1430)
21salva_recorde("Diego", 800)
22
23carrega_recordes.each_with_index do |recorde, indice|
24  puts "#{indice + 1}. #{recorde['nome']}: #{recorde['pontos']}"
25end
1. Carla: 1430
2. Ana: 1200
3. Bruno: 950

Os 800 pontos do Diego não entraram no top 3. Rode de novo, e os recordes continuam lá: esse é justamente o propósito de salvar num arquivo.

Quiz: (1) O "w" apaga o arquivo e começa do zero; o "a" mantém o conteúdo e acrescenta no fim. (2) O File.foreach, que segura uma linha por vez. (3) Exception também pega os seus próprios bugs e até o Ctrl+C; trate só o erro que você espera. (4) A quebra de linha (\n, ou \r\n) no fim de um texto. (5) O Ruby fecha o arquivo quando o bloco termina, mesmo que aconteça um erro dentro dele.

Cola rápida

Eu quero…Escreva
Ler o arquivo inteiroFile.read("notas.txt")
Pegar um array de linhasFile.readlines("notas.txt", chomp: true)
Ir linha por linha (arquivos grandes)File.foreach("notas.txt") { |linha| … }
Numerar as linhasFile.foreach(nome).with_index(1) { |linha, numero| … }
Verificar se um arquivo existeFile.exist?("notas.txt")
Lidar com um arquivo que não existebegin … rescue Errno::ENOENT => erro … end
Escrever um arquivo novoFile.write("notas.txt", texto) ou File.open(nome, "w") { |arquivo| arquivo.puts … }
Acrescentar no fimFile.write(nome, texto, mode: "a") ou File.open(nome, "a") { … }
Salvar / carregar dadosFile.write(nome, JSON.pretty_generate(dados)) / JSON.parse(File.read(nome))
Criar pastasFileUtils.mkdir_p("a/b/c")
Montar um caminhoFile.join("anotacoes", "2026", "janeiro.txt")
Achar arquivosDir.glob("anotacoes/**/*.txt")
Ler ou escrever dados bináriosmodos "rb" / "wb", ou File.binread

Resumindo

Arquivos são o jeito de os programas se lembrarem das coisas. Em Ruby, trabalhar com eles é curto e agradável:

  • Três jeitos de ler: File.read (uma string), File.readlines (um array), File.foreach (uma linha por vez, e o único cuja memória ficou estável no nosso teste com 146 MB).
  • Arquivos que não existem geram Errno::ENOENT: verifique com File.exist? ou trate esse erro específico com rescue.
  • Os modos importam: "w" apaga, "a" acrescenta, "r" lê. Acrescente b para arquivos binários.
  • Blocos fecham os arquivos para você, mesmo quando algo dá errado.
  • O JSON salva dados estruturados que sobrevivem entre uma execução e outra.
  • O texto é UTF-8 e, no Windows, o modo texto traduz em silêncio as quebras de linha \r\n.

Para conhecer melhor a linguagem, leia O Que É a Linguagem de Programação Ruby?.

Obrigado pela leitura!

Conhece alguém que vai gostar? Mande para essa pessoa.

Mais artigos

Leia a seguir

Comentários

Seja gentil e específico. Comentários com links de contas novas aparecem depois da análise de um moderador.