Como ler e escrever arquivos de texto com Java

Neste artigo eu apresento alguns casos de usos simples de leitura e escrita de arquivos de texto com Java.

Leitura

O código abaixo mostra como retornar todo o conteúdo de um arquivo de texto como uma String.

import static java.nio.charset.StandardCharsets.UTF_16;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ReadingAllContent {
  public static void main(String... args) {
    try {
      Path path = Paths.get("text.txt");
      byte[] bytes = Files.readAllBytes(path);
      String content = new String(bytes, UTF_16);
      System.out.println(content);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Com Java 11 ou mais recente o código fica mais simples usando o método Files#readString:

Path path = Path.of("text.txt");
String content = Files.readString(path, UTF_16);

Também é possível retornar todas as linhas do arquivo como uma lista de String usando o método Files#readAllLines.

Path path = Paths.get("text.txt");
List<String> lines = Files.readAllLines(path, UTF_16);
lines.forEach(System.out::println);

Os métodos acima carregam todo o conteúdo do arquivo na memória de uma só vez, por isso só devem ser usados quando o arquivo não for tão grande.

Para ler arquivos maiores, linha a linha, podemos usar o método Files#lines que retorna uma Stream que lê as linhas conforme é consumida.

import static java.nio.charset.StandardCharsets.UTF_16;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class ReadingAsStream {
  public static void main(String... args) {
    Path path = Paths.get("text.txt");

    try (Stream<String> stream = Files.lines(path, UTF_16)) {
      stream.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

A Stream retornada precisa ser fechada quando não for mais útil, por isso, no exemplo eu utilizei o try-with-resource que garante seu fechamento.

Escrita

O código abaixo mostra como escrever uma String em um arquivo.

import static java.nio.charset.StandardCharsets.UTF_16;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class WritingString {
  public static void main(String... args) {
    try {
      Path path = Paths.get("text.txt");
      String content = "abc";
      byte[] bytes = content.getBytes(UTF_16);
      Files.write(path, bytes);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Com Java 11 ou mais recente o código fica mais simples usando o método Files#writeString.

Path path = Path.of("text.txt");
Files.writeString(path, "abc", UTF_16);

O método Files#write também aceita uma lista de String como argumento.

Path path = Paths.get("text.txt");
List<String> lines = Arrays.asList("a", "b", "c");
Files.write(path, lines, UTF_16);

Neste caso, cada String da lista será escrita como uma nova linha no arquivo.

Observação 1: Escolhendo o charset

Nos exemplos acima eu passei o Charset UTF-16 explicitamente apenas para mostrar que é possível, pois nem sempre é necessário.

O método Files#readString, por exemplo, poderia ser invocado assim:

Path path = Paths.get("text.txt");
String content = Files.readString(path);

Neste caso o charset usado por padrão será o UTF-8 e o mesmo vale para os métodos mostrados abaixo:

Path path = Paths.get("text.txt");

String a = Files.readString(path);

List<String> b = Files.readAllLines(path);

Stream<String> c = Files.lines(path);

Files.writeString(path, "abc");

Files.write(path, Arrays.asList("a", "b", "c"));

Já no método String#getBytes, se o charset não for passado explicitamente, será usado o charset padrão da sua plataforma. Para obter o charset padrão, você pode usar o método abaixo:

Charset charset = Charset.defaultCharset();

Por fim, a classe StandardCharsets possui constantes apenas para os charsets que são requeridos por qualquer implementação da plataforma Java. Se você precisar de um charset não definido nesta classe, é possível obter da seguinte forma:

Charset charset = Charset.forName("UTF-32");

Se o charset desejado for suportado pela JVM, uma instância de Charset será retornada, caso contrário uma exceção será lançada.

Observação 2: Outras opções

Os métodos de escrita Files#writeString e Files#write também aceitam opções extras.

Por padrão eles criarão um novo arquivo caso não exista ou sobrescreverão o conteúdo de um arquivo existente, mas é possível mudar este comportamento.

Considere o código abaixo:

import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.CREATE_NEW;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class WritingWithOptions {
  public static void main(String... args) throws IOException {
    byte[] content = "abc".getBytes();

    /* 1 */ Files.write(Paths.get("a.txt"), content, APPEND);
    /* 2 */ Files.write(Paths.get("b.txt"), content, CREATE, APPEND);
    /* 3 */ Files.write(Paths.get("c.txt"), content, CREATE_NEW);
  }
}

O exemplo 1 acrescentará content à um arquivo existente e lançará uma exceção caso o arquivo não exista.

O exemplo 2 é parecido com o primeiro, mas criará um novo arquivo caso não exista ao invés de lançar uma exceção.

Já no exemplo 3 ele sempre tentará criar um novo arquivo e lançará uma exceção se o arquivo já existir.

Há outras opções disponíveis na classe StandardOpenOption, consulte a documentação para saber mais.

Conclusão

Há outras formas de ler e escrever arquivos em Java e compreender os métodos acima é um bom ponto de partida antes de partir para casos mais complexos.

Se encontrar algum erro ou tiver alguma informação adicional, não deixe de usar os comentários.

13

This website collects cookies to deliver better user experience