Leia todo o texto de um arquivo
O Java 11 adicionou o método readString () para ler arquivos pequenos como um String
, preservando os terminadores de linha:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Para versões entre Java 7 e 11, aqui está um idioma compacto e robusto, agrupado em um método utilitário:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Ler linhas de texto de um arquivo
O Java 7 adicionou um método de conveniência para ler um arquivo como linhas de texto, representadas como a List<String>
. Essa abordagem é "com perda" porque os separadores de linha são removidos do final de cada linha.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
O Java 8 adicionou o Files.lines()
método para produzir a Stream<String>
. Novamente, esse método está com perdas porque os separadores de linha são removidos. Se um IOException
for encontrado durante a leitura do arquivo, ele será agrupado em um UncheckedIOException
, já Stream
que não aceita lambdas que geram exceções verificadas.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Isso Stream
precisa de uma close()
ligação; isso está mal documentado na API e suspeito que muitas pessoas nem percebem que Stream
tem umclose()
método. Certifique-se de usar um bloco ARM, como mostrado.
Se você estiver trabalhando com uma fonte que não seja um arquivo, poderá usar o lines()
método emBufferedReader
vez disso.
Utilização de memória
O primeiro método, que preserva as quebras de linha, pode exigir temporariamente memória várias vezes o tamanho do arquivo, porque por um curto período de tempo o conteúdo do arquivo bruto (uma matriz de bytes) e os caracteres decodificados (cada um com 16 bits, mesmo que codificado) 8 bits no arquivo) residem na memória de uma só vez. É mais seguro aplicar a arquivos que você sabe serem pequenos em relação à memória disponível.
O segundo método, linhas de leitura, geralmente é mais eficiente em memória, porque o buffer de bytes de entrada para decodificação não precisa conter o arquivo inteiro. No entanto, ainda não é adequado para arquivos muito grandes em relação à memória disponível.
Para ler arquivos grandes, você precisa de um design diferente para o seu programa, que leia um pedaço de texto de um fluxo, o processe e depois passe para o próximo, reutilizando o mesmo bloco de memória de tamanho fixo. Aqui, "grande" depende das especificações do computador. Atualmente, esse limite pode ser de muitos gigabytes de RAM. O terceiro método, usando a, Stream<String>
é uma maneira de fazer isso, se os "registros" de entrada forem linhas individuais. (Usar o readLine()
método de BufferedReader
é o equivalente processual a essa abordagem.)
Codificação de caracteres
Uma coisa que está faltando na amostra na postagem original é a codificação de caracteres. Existem alguns casos especiais em que o padrão da plataforma é o que você deseja, mas eles são raros e você deve justificar sua escolha.
A StandardCharsets
classe define algumas constantes para as codificações necessárias para todos os tempos de execução do Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
O padrão da plataforma está disponível naCharset
própria classe :
String content = readFile("test.txt", Charset.defaultCharset());
Nota: Esta resposta substitui amplamente minha versão do Java 6. O utilitário do Java 7 simplifica com segurança o código, e a resposta antiga, que usava um buffer de bytes mapeados, impedia que o arquivo lido fosse excluído até que o buffer mapeado fosse coletado de lixo. Você pode visualizar a versão antiga através do link "editado" nesta resposta.