Especialização em Sistemas com Java 21 LTS • Capítulo 12


🎯 Visão Geral dos Exemplos Práticos

Neste laboratório prático, implementaremos exemplos corporativos completos explorando:

  1. Pipeline de Ingestão de Dados com NIO.2: criação estruturada de diretórios, escrita bufferizada em UTF-8 e leitura de linhas com streams preguiçosos.
  2. Varredura Recursiva com Files.walk: catalogação e auditoria forense de arquivos de log por extensão e tamanho em disco.
  3. Operações Atômicas de Sistema de Arquivos: movimentação atômica de arquivos de lote (ATOMIC_MOVE) para garantir tolerância a falhas.

💻 Exemplo 01 — Pipeline de Processamento e Transição de Lotes com Java NIO.2

package com.empresa.arquivos;

import java.io.BufferedWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.time.LocalDate;
import java.util.stream.Stream;

/**
 * Pipeline corporativo de ingestão, cálculo e arquivamento de remessas com NIO.2.
 */
public class PipelineIngestaoLotes {

    public record RegistroFinanceiro(long id, String sacado, BigDecimal valor, boolean liquidado) {}

    public static void main(String[] args) {
        System.out.println("================================================================================");
        System.out.println("          PIPELINE DE PROCESSAMENTO DE ARQUIVOS COM JAVA NIO.2 (JAVA 21)        ");
        System.out.println("================================================================================");

        try {
            // Criação de diretório temporário isolado para a execução
            Path dirTrabalho = Files.createTempDirectory("pipeline_lotes_");
            Path dirEntrada = dirTrabalho.resolve("inbound");
            Path dirProcessados = dirTrabalho.resolve("archive");

            Files.createDirectories(dirEntrada);
            Files.createDirectories(dirProcessados);

            Path arquivoRemessa = dirEntrada.resolve("remessa_" + LocalDate.now() + ".csv");

            // 1. Geração do Arquivo de Dados com BufferedWriter
            try (BufferedWriter writer = Files.newBufferedWriter(arquivoRemessa, StandardCharsets.UTF_8,
                    StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
                writer.write("ID;SACADO;VALOR;STATUS\n");
                writer.write("1001;Hospital Santa Cruz;54200.00;LIQUIDADO\n");
                writer.write("1002;Universidade Federal;18900.50;PENDENTE\n");
                writer.write("1003;Rede Varejo S/A;89450.75;LIQUIDADO\n");
                writer.write("1004;Distribuidora Alimentos;12300.00;LIQUIDADO\n");
            }

            System.out.printf("📁 [1/4] Remessa gerada no diretório: %s%n", arquivoRemessa.toAbsolutePath());
            System.out.printf("   Tamanho do arquivo gerado: %d bytes%n%n", Files.size(arquivoRemessa));

            // 2. Leitura com Stream lazy (Files.lines) e Processamento
            System.out.println("🔍 [2/4] Processando registros da remessa...");
            BigDecimal totalLiquidado = BigDecimal.ZERO;
            int totalRegistros = 0;

            try (Stream<String> linhas = Files.lines(arquivoRemessa, StandardCharsets.UTF_8)) {
                for (String linha : (Iterable<String>) linhas.skip(1)::iterator) {
                    if (linha.isBlank()) continue;
                    String[] tokens = linha.split(";");
                    long id = Long.parseLong(tokens[0]);
                    String sacado = tokens[1];
                    BigDecimal valor = new BigDecimal(tokens[2]);
                    boolean liquidado = "LIQUIDADO".equalsIgnoreCase(tokens[3]);

                    if (liquidado) {
                        totalLiquidado = totalLiquidado.add(valor);
                        System.out.printf("   ✅ Remessa #%d - %-25s | R$ %10.2f [PROCESSADA]%n", id, sacado, valor);
                    } else {
                        System.out.printf("   ⏳ Remessa #%d - %-25s | R$ %10.2f [AGUARDANDO]%n", id, sacado, valor);
                    }
                    totalRegistros++;
                }
            }

            System.out.println("--------------------------------------------------------------------------------");
            System.out.printf("Total de Títulos Apurados: %d registros%n", totalRegistros);
            System.out.printf("Volume Total Liquidado   : R$ %,10.2f%n", totalLiquidado);

            // 3. Movimentação Atômica para a pasta de arquivos processados
            Path destinoFinal = dirProcessados.resolve(arquivoRemessa.getFileName());
            Files.move(arquivoRemessa, destinoFinal, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
            System.out.printf("%n🚚 [3/4] Arquivo transferido atomicamente para: %s%n", destinoFinal);

            // 4. Verificação de integridade pós-movimentação
            boolean origemExiste = Files.exists(arquivoRemessa);
            boolean destinoExiste = Files.exists(destinoFinal);
            System.out.printf("🔒 [4/4] Integridade: Origem excluída? %b | Destino ativo? %b%n", !origemExiste, destinoExiste);

            // Limpeza final do diretório temporário
            Files.deleteIfExists(destinoFinal);
            Files.deleteIfExists(dirEntrada);
            Files.deleteIfExists(dirProcessados);
            Files.deleteIfExists(dirTrabalho);

        } catch (IOException e) {
            System.err.printf("🚨 Erro de I/O no pipeline: %s%n", e.getMessage());
        }

        System.out.println("================================================================================");
    }
}

💻 Exemplo 02 — Varredura e Auditoria Recursiva de Pastas com Files.walk

package com.empresa.arquivos;

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

/**
 * Auditoria de armazenamento em disco inspecionando árvores de diretórios.
 */
public class AuditorArmazenamentoDisco {

    public static void main(String[] args) {
        System.out.println("================================================================================");
        System.out.println("              AUDITORIA FORENSE DE DIRETÓRIOS COM FILES.WALK                    ");
        System.out.println("================================================================================");

        Path raizAuditoria = Path.of(System.getProperty("user.dir"));
        System.out.printf("Inspecionando diretório de trabalho: [%s]%n%n", raizAuditoria.toAbsolutePath());

        try (Stream<Path> caminhos = Files.walk(raizAuditoria, 3)) {
            caminhos.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".md"))
                    .limit(10)
                    .forEach(arquivo -> {
                        try {
                            long bytes = Files.size(arquivo);
                            System.out.printf("📄 %-45s | %8d bytes%n", 
                                    arquivo.getFileName(), bytes);
                        } catch (IOException ignored) {}
                    });
        } catch (IOException e) {
            System.err.println("Falha na varredura: " + e.getMessage());
        }

        System.out.println("================================================================================");
    }
}

📋 Resultado Esperado no Console

================================================================================
          PIPELINE DE PROCESSAMENTO DE ARQUIVOS COM JAVA NIO.2 (JAVA 21)        
================================================================================
📁 [1/4] Remessa gerada no diretório: C:\Users\AppData\Local\Temp\pipeline_lotes_...\inbound\remessa_2026-09-28.csv
   Tamanho do arquivo gerado: 174 bytes

🔍 [2/4] Processando registros da remessa...
   ✅ Remessa #1001 - Hospital Santa Cruz       | R$   54200.00 [PROCESSADA]
   ⏳ Remessa #1002 - Universidade Federal      | R$   18900.50 [AGUARDANDO]
   ✅ Remessa #1003 - Rede Varejo S/A           | R$   89450.75 [PROCESSADA]
   ✅ Remessa #1004 - Distribuidora Alimentos   | R$   12300.00 [PROCESSADA]
--------------------------------------------------------------------------------
Total de Títulos Apurados: 4 registros
Volume Total Liquidado   : R$ 155.950,75

🚚 [3/4] Arquivo transferido atomicamente para: C:\Users\AppData\Local\Temp\pipeline_lotes_...\archive\remessa_2026-09-28.csv
🔒 [4/4] Integridade: Origem excluída? true | Destino ativo? true
================================================================================