Leitura de arquivos em Java: exemplos e diferenças entre as versões 6, 7 e 11
Existem várias maneiras de manipular arquivos em Java, principalmente por conta da evolução do Java.
Os pacotes java.io e java.nio são responsáveis pela entrada e saída de dados em Java. Embora ambos forneçam funcionalidades semelhantes, existem diferenças importantes entre eles.
O pacote java.io foi introduzido nas primeiras versões do Java e, ao longo dos anos, sofreu evoluções significativas para melhorar a eficiência e escalabilidade das operações de E/S.
Já o pacote java.nio fornece funcionalidades mais avançadas para entrada/saída de dados em Java. Ele foi introduzido na versão 1.4 do Java e é uma alternativa mais eficiente e escalável ao pacote java.io. Ele usa buffers para armazenar dados em memória e pode trabalhar com canais para executar operações de E/S não bloqueantes.
Na versão 7 do Java, o pacote java.nio sofreu algumas atualizações significativas. Algumas das melhorias incluem:
-
Melhorias na classe ByteBuffer: A classe ByteBuffer foi atualizada com novos métodos para trabalhar com buffers, como putChar() e getChar() para colocar e obter caracteres de um buffer.
-
Melhorias na classe Path: A classe Path foi introduzida na versão 7 do Java e fornece uma maneira mais flexível de trabalhar com caminhos de arquivos do que a classe File. Ela fornece métodos para trabalhar com caminhos relativos, caminhos com links simbólicos e muito mais.
-
Melhorias na classe Files: A classe Files foi atualizada com novos métodos para trabalhar com arquivos e diretórios, como newByteChannel() para criar um canal de bytes para um arquivo e move() para mover um arquivo ou diretório.
-
Melhorias na classe WatchService: A classe WatchService foi introduzida na versão 7 do Java e permite que você monitore eventos em um diretório, como criação, exclusão e modificação de arquivos.
Na versão 11 do Java, o pacote java.nio sofreu outras atualizações significativas. Algumas das melhorias incluem:
-
Melhorias na classe Files: A classe Files foi atualizada com novos métodos para trabalhar com arquivos e diretórios, como readString() para ler o conteúdo de um arquivo como uma String e writeString() para escrever uma String em um arquivo.
-
Melhorias na classe Path: A classe Path foi atualizada com novos métodos para trabalhar com caminhos de arquivos, como normalize() para normalizar um caminho e relativize() para criar um caminho relativo entre dois caminhos.
-
Melhorias na classe FileSystem: A classe FileSystem foi atualizada com novos métodos para trabalhar com sistemas de arquivos, como isReadOnly() para verificar se um sistema de arquivos é somente leitura e newFileSystem() para criar um novo sistema de arquivos.
Essas são apenas algumas das melhorias introduzidas nas versões 7 e 11 do pacote java.nio. Em geral, essas melhorias tornam mais fácil e eficiente a manipulação de entrada/saída de dados em Java, especialmente para operações que envolvem arquivos e diretórios.
Exemplos de leituras de arquivos
Suponha que queremos obter o conteúdo do arquivo de texto chamado
no diretório exemplo.txt
do windows.C:
Java 11+
String texto = Files.readString(Path.of("C:/exemplo.txt"));
Lê todo o conteúdo de um arquivo em uma string, decodificando de bytes para caracteres usando o conjunto de caracteres UTF-8. O método garante que o arquivo seja fechado quando todo o conteúdo tiver sido lido ou um erro de E/S ou outra exceção de tempo de execução for lançada.
Java 7+
String texto = new String(Files.readAllBytes(Path.of("C:/exemplo.txt")))
Lê todos os bytes de um arquivo. O método garante que o arquivo seja fechado quando todos os bytes tiverem sido lidos ou um erro de E/S ou outra exceção de tempo de execução for lançada. Esse método destina-se a casos simples em que é conveniente ler todos os bytes em uma matriz de bytes. Não se destina à leitura de arquivos grandes.
Java 6-
FileReader leitor = null;
BufferedReader bufferedReader = null;
try {
leitor = new FileReader("C:/exemplo.txt");
bufferedReader = new BufferedReader(leitor);
String linha;
StringBuilder conteudoArquivo = new StringBuilder();
// Lê cada linha do arquivo e adiciona à string conteudoArquivo
while ((linha = bufferedReader.readLine()) != null) {
conteudoArquivo.append(linha).append("\n");
}
String texto = conteudoArquivo.toString();
System.out.println(texto);
} catch (IOException e) {
System.out.println("Erro ao ler o arquivo: " + e.getMessage());
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
if (leitor != null) {
leitor.close();
}
}
FileReader recebe o caminho do arquivo como parâmetro e um objeto BufferedReader que lê cada linha do arquivo usando o método readLine(). Temos que tomar o cuidado de fechar o BufferedReader e FileReader após a operação.
Guava
String texto = Files.toString(new File("C:/exemplo.txt"), Charsets.UTF_8);
Lê todos os caracteres de um arquivo em uma String, usando o conjunto de caracteres fornecido.
Necessário adicionar a seguinte dependencia em seu projeto:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
CommonsIO
String texto = FileUtils.readFileToString(new File("C:/exemplo.txt"), "UTF-8");
Assim como no caso do Guava lê todos os caracteres de um arquivo em uma String, usando o conjunto de caracteres fornecido.
Deve-se incluir a seguinte dependencia em seu projeto:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
Conclusão:
Manipulação de arquivos é uma tarefa comum em muitos projetos de software. Em Java, podemos utilizar os pacotes java.io e java.nio para realizar operações de entrada/saída de dados. Ambos pacotes possuem funcionalidades semelhantes, porém, java.nio fornece funcionalidades mais avançadas, com melhorias significativas nas versões 7 e 11 do Java, mas caso esteja utilizando uma versão anterior a adicionar de uma biblioteca auxiliar é a melhor opção.