A API NIO.2 (New I/O) do Java introduz várias melhorias para trabalhar com arquivos e diretórios, incluindo a classe Paths, Files, e Path. Quando combinada com a API Stream, ela permite processar arquivos e diretórios de maneira eficiente, usando recursos como o Stream para ler, manipular e modificar dados de arquivos.
Abaixo estão alguns exemplos práticos de como usar a API Stream junto com NIO.2.
1. Listando Arquivos em um Diretório com Stream
Podemos usar a classe Files para listar arquivos em um diretório e aplicar operações de fluxo (Stream) sobre esses arquivos.
Exemplo de listagem de arquivos em um diretório:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class NIOStreamListarArquivos {
public static void main(String[] args) {
// Define o caminho do diretório
Path caminhoDiretorio = Paths.get("exemplo/diretorio");
try (Stream<Path> caminhos = Files.walk(caminhoDiretorio)) {
// Filtra apenas arquivos e imprime seus nomes
caminhos.filter(Files::isRegularFile)
.forEach(caminho -> System.out.println(caminho.getFileName()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
- Explicação: O método
Files.walk()retorna umStream<Path>contendo todos os caminhos dentro do diretório. O métodofilter(Files::isRegularFile)filtra apenas os arquivos (não diretórios), eforEach()é usado para imprimir o nome de cada arquivo.
2. Lendo Arquivos com Stream
Você também pode usar a API Stream para ler o conteúdo de um arquivo linha por linha.
Exemplo de leitura de um arquivo com Stream:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class NIOStreamLerArquivo {
public static void main(String[] args) {
// Define o caminho do arquivo
Path caminhoArquivo = Paths.get("exemplo/diretorio/arquivo.txt");
try (Stream<String> linhas = Files.lines(caminhoArquivo)) {
// Processa cada linha do arquivo
linhas.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- Explicação: O método
Files.lines()retorna umStream<String>com as linhas do arquivo. Você pode então processar as linhas do arquivo como qualquer outro stream, por exemplo, comforEach()para imprimir.
3. Filtrando Arquivos por Extensão
Você pode usar a API Stream para filtrar arquivos com base em uma condição, como a extensão do arquivo.
Exemplo de filtragem de arquivos por extensão:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class NIOStreamFiltrarArquivos {
public static void main(String[] args) {
// Define o caminho do diretório
Path caminhoDiretorio = Paths.get("exemplo/diretorio");
try (Stream<Path> caminhos = Files.walk(caminhoDiretorio)) {
// Filtra arquivos com extensão ".txt" e imprime seus nomes
caminhos.filter(p -> p.toString().endsWith(".txt"))
.forEach(caminho -> System.out.println(caminho.getFileName()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
- Explicação: A filtragem
filter(p -> p.toString().endsWith(".txt"))seleciona apenas arquivos com a extensão.txt.
4. Copiando Arquivos Usando Stream
Você pode combinar Stream com a operação de cópia de arquivos para processar e copiar arquivos de um diretório para outro.
Exemplo de cópia de arquivos com Stream:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class NIOStreamCopiarArquivos {
public static void main(String[] args) {
Path origem = Paths.get("exemplo/diretorio");
Path destino = Paths.get("exemplo/diretorio_destino");
try (Stream<Path> caminhos = Files.walk(origem)) {
// Cria o diretório de destino, se não existir
if (!Files.exists(destino)) {
Files.createDirectories(destino);
}
// Copia os arquivos para o novo diretório
caminhos.filter(Files::isRegularFile)
.forEach(caminhoOrigem -> {
Path caminhoDestino = destino.resolve(origem.relativize(caminhoOrigem));
try {
Files.copy(caminhoOrigem, caminhoDestino);
System.out.println("Arquivo copiado: " + caminhoDestino);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
- Explicação: O método
Files.copy()é usado para copiar arquivos de um diretório para outro. O métodoresolve()combina o diretório de destino com o caminho relativo do arquivo.
5. Concatenando o Conteúdo de Vários Arquivos com Stream
Você pode concatenar o conteúdo de vários arquivos em um único fluxo usando Stream.concat().
Exemplo de concatenação de arquivos:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class NIOStreamConcatenarArquivos {
public static void main(String[] args) {
Path caminhoArquivo1 = Paths.get("exemplo/diretorio/arquivo1.txt");
Path caminhoArquivo2 = Paths.get("exemplo/diretorio/arquivo2.txt");
try (Stream<String> stream1 = Files.lines(caminhoArquivo1);
Stream<String> stream2 = Files.lines(caminhoArquivo2)) {
// Concatena os dois streams e imprime o conteúdo
Stream<String> concatenado = Stream.concat(stream1, stream2);
concatenado.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- Explicação: O método
Stream.concat()concatena dois fluxos de dados. Nesse exemplo, concatenamos os fluxos de duas linhas de arquivos e os imprimimos.
📝 Resumo das Operações com Stream e NIO.2
- Listar Arquivos em um Diretório: Usamos
Files.walk()para obter um fluxo de arquivos e diretórios. - Ler Arquivos: Usamos
Files.lines()para ler um arquivo linha por linha como um fluxo de dados. - Filtrar Arquivos: Aplicamos filtros no fluxo de arquivos, como por exemplo, com a extensão
.txt. - Copiar Arquivos: Usamos o
Streampara copiar arquivos de um diretório para outro. - Concatenar Arquivos: Usamos
Stream.concat()para combinar o conteúdo de dois ou mais arquivos.
🧪 Quiz – 5 Questões Rápidas
- Qual método você usaria para listar arquivos de um diretório como um fluxo?
A)Files.walk()
B)Files.list()
C)Files.scan()
D)Files.find()
- Como você pode ler um arquivo linha por linha usando a API NIO?
A)Files.readLines()
B)Files.lines()
C)Files.stream()
D)Files.readAllLines()
- Qual método você usaria para copiar um arquivo para outro diretório?
A)Files.move()
B)Files.copy()
C)Files.transfer()
D)Files.save()
- Qual método é usado para concatenar dois fluxos de dados?
A)Stream.concat()
B)Stream.merge()
C)Stream.add()
D)Stream.join()
- Como você pode filtrar arquivos com extensão
.txtem um diretório?
A)Files.walk().filter(p -> p.endsWith(".txt"))
B)Files.walk().filter(p -> p.toString().endsWith(".txt"))
C)Files.walk().filter(p -> p.contains(".txt"))
D)Files.walk().filter(p -> p.getFileName().equals(".txt"))
✅ Gabarito Comentado
- A –
Files.walk()é o método correto para listar arquivos em um diretório como um fluxo. - B –
Files.lines()é usado para ler um arquivo linha por linha como um fluxo de strings. - B –
Files.copy()é o método para copiar um arquivo para outro diretório. - A –
Stream.concat()é o método usado para concatenar dois fluxos de dados. - B –
Files.walk().filter(p -> p.toString().endsWith(".txt"))filtra arquivos com a extensão.txt.