CodeGym /Cursos /JAVA 25 SELF /Leitura e escrita de arquivos: operações básicas

Leitura e escrita de arquivos: operações básicas

JAVA 25 SELF
Nível 35, Lição 2
Disponível

1. Leitura do arquivo inteiro

Leitura de todos os bytes

Às vezes é preciso extrair todo o conteúdo de um arquivo de uma só vez — como está, sem analisar, seja uma imagem, um arquivo compactado ou algum formato binário. Para isso, o Java tem o método Files.readAllBytes(path). Ele retorna um array de bytes (byte[]), ou seja, dados brutos do arquivo, que você pode usar como quiser.

import java.nio.file.*;

public class ReadBytesExample {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("example.txt");
        byte[] allBytes = Files.readAllBytes(path);
        System.out.println("Tamanho do arquivo em bytes: " + allBytes.length);
    }
}

Observação: Se o arquivo for grande (gigabytes), essa abordagem pode causar problemas de memória — afinal, todo o conteúdo do arquivo é carregado de uma vez na RAM.

Leitura de todas as linhas

Para arquivos de texto há um jeito mais amigável: Files.readAllLines(path). Ele retorna uma lista de linhas (List<String>), em que cada elemento é uma linha do arquivo (os separadores de linha são tratados automaticamente).

import java.nio.file.*;
import java.util.List;

public class ReadLinesExample {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("example.txt");
        List<String> lines = Files.readAllLines(path);

        for (String line : lines) {
            System.out.println(line);
        }
    }
}

Importante: Por padrão é usada a codificação do sistema. Se quiser especificar a codificação explicitamente (por exemplo, UTF-8), use a versão sobrecarregada do método:

List<String> lines = Files.readAllLines(path, java.nio.charset.StandardCharsets.UTF_8);

Exemplo: ler um arquivo e imprimir na tela

Vamos adicionar isso ao nosso miniaplicativo (por exemplo, um “bloco de notas” ou uma “lista de tarefas”):

import java.nio.file.*;
import java.util.List;

public class TodoReader {
    public static void main(String[] args) throws Exception {
        Path todoPath = Paths.get("todo.txt");
        if (Files.exists(todoPath)) {
            List<String> tasks = Files.readAllLines(todoPath);
            System.out.println("Suas tarefas para hoje:");
            for (String task : tasks) {
                System.out.println("- " + task);
            }
        } else {
            System.out.println("Arquivo todo.txt não encontrado. Crie uma lista de tarefas!");
        }
    }
}

2. Gravação em arquivo

Gravação de array de bytes

Se você tem um array de bytes (por exemplo, resultado de serialização, imagem, áudio), use Files.write(path, bytes). Esse método cria o arquivo se ele não existir ou sobrescreve o existente.

import java.nio.file.*;

public class WriteBytesExample {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("output.bin");
        byte[] data = {1, 2, 3, 4, 5};
        Files.write(path, data);
        System.out.println("Bytes gravados no arquivo output.bin");
    }
}

Gravação de lista de strings

Para arquivos de texto é mais conveniente usar uma lista de strings — cada linha será gravada separadamente, com quebra de linha.

import java.nio.file.*;
import java.util.Arrays;
import java.util.List;

public class WriteLinesExample {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("todo.txt");
        List<String> tasks = Arrays.asList(
            "Comprar leite",
            "Ligar para a avó",
            "Fazer a lição de casa de Java"
        );
        Files.write(path, tasks);
        System.out.println("Lista de tarefas gravada em todo.txt");
    }
}

Atenção: Por padrão o arquivo será sobrescrito! Se ele já existia, as tarefas antigas desaparecerão. (Como não perder o antigo — contaremos um pouco mais adiante.)

Gravar uma string em arquivo

Se quiser gravar apenas uma linha, crie uma lista com uma única string ou use Files.write(path, string.getBytes()):

import java.nio.file.*;

public class WriteStringExample {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("hello.txt");
        String message = "Olá, Java!";
        Files.write(path, message.getBytes());
        System.out.println("Linha gravada em hello.txt");
    }
}

Especificando a codificação explicitamente

Para evitar caracteres estranhos ao trabalhar com texto em russo (e não só), sempre especifique a codificação:

import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;

public class WriteLinesUtf8Example {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("hello.txt");
        List<String> lines = List.of("Olá, mundo!", "Isto é Java.");
        Files.write(path, lines, StandardCharsets.UTF_8);
    }
}

3. Tratamento de erros

Ao trabalhar com arquivos, o Java pode lançar a exceção IOException. É um sinal geral de que “algo deu errado” no nível de entrada e saída. As causas podem ser muitas: o arquivo simplesmente não existe, faltam permissões, o disco está cheio ou ocupado, ou às vezes até o pendrive foi desconectado no pior momento.

Por isso, os métodos de leitura e escrita de arquivos exigem que estejamos prontos para tratar tais situações. Isso é feito com try-catch:

import java.nio.file.*;
import java.util.List;
import java.io.IOException;

public class SafeReadExample {
    public static void main(String[] args) {
        Path path = Paths.get("todo.txt");
        try {
            List<String> lines = Files.readAllLines(path);
            System.out.println("Conteúdo do arquivo:");
            for (String line : lines) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            System.out.println("Erro ao ler o arquivo: " + ex.getMessage());
        }
    }
}

Por que tudo isso?

try-catch transforma um possível colapso do programa em uma situação controlada. Se o arquivo não existir — informamos o usuário calmamente. Se o sistema não der acesso — apontamos o problema. E se o disco “sumir” no meio da operação, o programa não vai cair com um stack trace assustador; ao menos avisará com uma mensagem normal. Em outras palavras: IOException não é um inimigo, é apenas a forma de o Java nos dizer: “ei, algo lá fora deu errado; pense no que fazer a seguir”.

4. Exemplos práticos

Ler um arquivo e exibir o conteúdo

import java.nio.file.*;
import java.util.List;
import java.io.IOException;

public class PrintFileExample {
    public static void main(String[] args) {
        Path path = Paths.get("notes.txt");
        try {
            if (!Files.exists(path)) {
                System.out.println("Arquivo notes.txt não encontrado.");
                return;
            }
            List<String> lines = Files.readAllLines(path, java.nio.charset.StandardCharsets.UTF_8);
            System.out.println("Conteúdo do arquivo notes.txt:");
            for (String line : lines) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Erro ao ler o arquivo: " + e.getMessage());
        }
    }
}

Gravar uma string em um novo arquivo

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.IOException;

public class WriteFileExample {
    public static void main(String[] args) {
        Path path = Paths.get("greeting.txt");
        String content = "Bem-vindo ao mundo do Java IO!";
        try {
            Files.write(path, content.getBytes(StandardCharsets.UTF_8));
            System.out.println("Linha gravada no arquivo greeting.txt");
        } catch (IOException e) {
            System.out.println("Erro ao gravar o arquivo: " + e.getMessage());
        }
    }
}

Gravar uma lista de strings em arquivo

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.io.IOException;

public class WriteListExample {
    public static void main(String[] args) {
        Path path = Paths.get("shopping.txt");
        List<String> items = List.of("Pão", "Leite", "Queijo");
        try {
            Files.write(path, items, StandardCharsets.UTF_8);
            System.out.println("Lista de compras gravada em shopping.txt");
        } catch (IOException e) {
            System.out.println("Erro ao gravar o arquivo: " + e.getMessage());
        }
    }
}

5. Resumo sobre streams

Os métodos Files.readAllBytes, Files.readAllLines, Files.write são “tudo de uma vez”: ou todo o arquivo vai para a memória, ou todo o conteúdo é gravado de uma vez no disco. Para arquivos pequenos isso é prático, mas para arquivos grandes nem tanto (você pode ter OutOfMemoryError ou simplesmente “travar” ao ler logs de gigabytes).

Para trabalhar com arquivos grandes ou leitura linha a linha usam-se streams:

  • Para texto: BufferedReader, BufferedWriter
  • Para bytes: InputStream, OutputStream

Falaremos mais sobre streams nas próximas aulas, mas aqui vai um pequeno teaser:

import java.nio.file.*;
import java.io.*;

public class BufferedReaderExample {
    public static void main(String[] args) {
        Path path = Paths.get("bigfile.txt");
        try (BufferedReader reader = Files.newBufferedReader(path)) {
            String line;
            while ((line = reader.readLine()) != null) {
                // Processando a linha
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Erro ao ler o arquivo: " + e.getMessage());
        }
    }
}

6. Detalhes úteis

  • Sobrescrita de arquivo: Todos os métodos Files.write sobrescrevem o arquivo por padrão. Se precisar adicionar no final, use opções adicionais (falaremos sobre isso na próxima aula).
  • Codificação: Sempre especifique a codificação explicitamente ao trabalhar com texto não ASCII. Isso evita “caracteres estranhos” na saída. Uma boa escolha é StandardCharsets.UTF_8.
  • Caminhos: Use Paths.get(...) para garantir multiplataforma. Nunca faça hardcode das barras (/ ou \) manualmente.
  • Nomes de arquivos: Não use caracteres proibidos no nome do arquivo (?, *, :, <, >, | etc.), especialmente se seu código precisar rodar no Windows.

7. Erros comuns ao ler e escrever arquivos

Erro nº 1: IOException não é tratada. Com frequência iniciantes escrevem Files.readAllLines(path) sem try-catch, e no primeiro problema (arquivo não encontrado, falta de permissão, disco corrompido) o programa cai. Sempre trate as exceções!

Erro nº 2: trabalhar com arquivos grandes usando readAllBytes/readAllLines. Se o arquivo tem centenas de megabytes ou gigabytes, tentar carregá-lo inteiro pode “matar” seu programa. Para esses casos use streams (BufferedReader).

Erro nº 3: codificação não especificada na gravação/leitura de texto. Se você não especificar a codificação, o resultado pode variar entre computadores e sistemas operacionais. O problema aparece com frequência com alfabetos como o cirílico. Use StandardCharsets.UTF_8 ou a codificação necessária explicitamente.

Erro nº 4: achar que File/Path é o próprio arquivo. A classe File ou Path é apenas um “atalho” para o arquivo, não o arquivo em si. Ao criar o objeto você não cria o arquivo no disco. Para criar o arquivo — use os métodos Files.createFile, Files.write e assim por diante.

Erro nº 5: não fechar o stream (se você usa streams). Se você usa streams manualmente (por exemplo, BufferedReader), feche-os sempre (de preferência com try-with-resources). Caso contrário, o arquivo pode ficar “bloqueado” e indisponível para outros programas.

1
Tarefa
JAVA 25 SELF, nível 35, lição 2
Bloqueado
Quanto espaço ocupa o seu "secreto" documento? 📜
Quanto espaço ocupa o seu "secreto" documento? 📜
1
Tarefa
JAVA 25 SELF, nível 35, lição 2
Bloqueado
Visualização do registro de eventos do sistema 💻
Visualização do registro de eventos do sistema 💻
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION