Gerenciamento de Arquivos com a Classe Files do Java NIO.2

A partir do Java Development Kit (JDK) 1.7, o pacote java.nio.file introduziu a API NIO.2, trazendo melhorias significativas para a manipulação de sistemas de arquivos. Um dos componentes mais poderosos dessa API é a classe Files, que oferece métodos estáticos para operações comuns e avançadas em arquivos e diretórios de forma mais robusta e eficiente do que a API java.io.File legada.

1. Verificação da Existência de Arquivos

O método Files.exists(), parte da API NIO.2, é uma maneira robusta de verificar a presença de um arquivo ou diretório. Ao contrário do método mais antigo File.exists(), ele oferece flexibilidade adicional através do parâmetro LinkOption.

O LinkOption é um argumento opcional que define como os links simbólicos (atalhos para outros arquivos ou diretórios) devem ser tratados:

  • Se nenhum LinkOption for fornecido (comportamento padrão), o método segue os links simbólicos. Isso significa que ele verificará se o destino do link existe, não o link em si.
  • Se LinkOption.NOFOLLOW_LINKS for passado, o método não segue os links simbólicos. Ele apenas verifica a existência do próprio link simbólico, sem se importar com o que ele aponta.

É importante notar que, para arquvios ou diretórios que não são links simbólicos, a presença ou ausência de LinkOption.NOFOLLOW_LINKS não altera o comportamanto do método, pois ele sempre verificará a existência do item diretamente na localização especificada.


package com.exemplos.nio;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Collections;

public class GerenciadorDeArquivosNIO {

    public static void demoCheckFileStatus(String filePath) {
        Path targetPath = Paths.get(filePath);
        System.out.println("Verificando existência para: " + filePath);

        // Usando a API File (legada)
        boolean existeComFile = new File(filePath).exists();
        System.out.println("  Existe (java.io.File): " + existeComFile);

        // Usando Files.exists() (NIO.2)
        boolean existeComFiles = Files.exists(targetPath);
        System.out.println("  Existe (java.nio.file.Files): " + existeComFiles);

        // Exemplo com LinkOption.NOFOLLOW_LINKS (se fosse um link simbólico)
        // boolean existeSemSeguirLinks = Files.exists(targetPath, LinkOption.NOFOLLOW_LINKS);
        // System.out.println("  Existe (Files sem seguir links): " + existeSemSeguirLinks);
    }

    // ... (outros métodos virão abaixo)
}

2. Cópia de Arquivos

A classe Files simplifica significativamente a cópia de arquivos com seu método copy(). Este método requer o caminho de origem (Path), o caminho de destino (Path) e, opcionalmente, uma ou mais opções de cópia.

Cópia Básica

Para uma cópia simples, onde o arquivo de destino não precisa de uma estrutura de diretórios pré-existente ou você tem certeza de que ela existe, você pode usar StandardCopyOption.REPLACE_EXISTING para sobrescrever o arquivo de destino se ele já existir.


package com.exemplos.nio;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Collections;

public class GerenciadorDeArquivosNIO {

    // ... (método demoCheckFileStatus aqui)

    /**
     * Realiza uma cópia básica de um arquivo.
     * Presume que o diretório pai do destino já existe.
     */
    public static boolean performBasicFileCopy(String originPathStr, String targetPathStr) {
        Path origin = Paths.get(originPathStr);
        Path target = Paths.get(targetPathStr);
        try {
            Files.copy(origin, target, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("Cópia básica bem-sucedida de \"" + originPathStr + "\" para \"" + targetPathStr + "\"");
            return true;
        } catch (IOException ex) {
            System.err.println("Erro ao realizar cópia básica de \"" + originPathStr + "\": " + ex.getMessage());
            return false;
        }
    }

    // ... (outros métodos virão abaixo)
}

Cópia Robusta com Criação de Diretórios

Um problema comum com o método Files.copy() é que ele lança uma IOException se o diretório pai do arquivo de destino não existir. Para tornar a operação de cópia mais robusta, é uma boa prática verificar e criar os diretórios pai necessários antes de tentar a cópia.

O método Files.createDirectories() é ideal para isso, pois cria todos os diretórios intermediários ausentes, se necessário, e não faz nada se o diretório já existir.


package com.exemplos.nio;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Collections;

public class GerenciadorDeArquivosNIO {

    // ... (método demoCheckFileStatus e performBasicFileCopy aqui)

    /**
     * Realiza uma cópia de arquivo, garantindo que o diretório pai do destino exista.
     */
    public static boolean robustFileCopy(String inputSource, String outputDestination) {
        Path sourceFile = Paths.get(inputSource);
        Path targetFile = Paths.get(outputDestination);
        Path parentDirectory = targetFile.getParent();

        try {
            if (parentDirectory != null && !Files.exists(parentDirectory)) {
                Files.createDirectories(parentDirectory);
                System.out.println("Diretório pai criado: " + parentDirectory);
            }
            Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("Cópia robusta bem-sucedida de \"" + inputSource + "\" para \"" + outputDestination + "\"");
            return true;
        } catch (IOException ex) {
            System.err.println("Falha na cópia robusta de \"" + inputSource + "\": " + ex.getMessage());
            return false;
        }
    }

    public static void main(String[] args) {
        String currentDir = System.getProperty("user.dir");
        String sourceFileName = "arquivo_origem_demo.txt";
        String destBasicFileName = "copia_basica_demo.txt";
        String destRobustDirName = "novo_diretorio_exemplo";
        String destRobustFileName = "copia_robusta_demo.txt";

        String sourceFilePath = currentDir + File.separator + sourceFileName;
        String destBasicFilePath = currentDir + File.separator + destBasicFileName;
        String destRobustDirPath = currentDir + File.separator + destRobustDirName + File.separator + destRobustFileName;

        // 1. Criar um arquivo de origem de demonstração
        try {
            Files.write(Paths.get(sourceFilePath), "Conteúdo de teste para o arquivo de origem.".getBytes());
            System.out.println("Arquivo de origem criado: " + sourceFilePath);
        } catch (IOException e) {
            System.err.println("Erro ao criar arquivo de origem: " + e.getMessage());
            return; // Sair se o arquivo de origem não puder ser criado
        }

        System.out.println("\n--- Demonstração de Verificação de Existência de Arquivos ---");
        demoCheckFileStatus(sourceFilePath);
        demoCheckFileStatus(currentDir + File.separator + "arquivo_nao_existe_demo.txt");

        System.out.println("\n--- Demonstração de Cópia Básica de Arquivos ---");
        performBasicFileCopy(sourceFilePath, destBasicFilePath);

        System.out.println("\n--- Demonstração de Cópia Robusta de Arquivos (com criação de diretório) ---");
        robustFileCopy(sourceFilePath, destRobustDirPath);

        // 3. Limpeza dos arquivos e diretórios criados (opcional)
        try {
            Files.deleteIfExists(Paths.get(sourceFilePath));
            Files.deleteIfExists(Paths.get(destBasicFilePath));
            Files.deleteIfExists(Paths.get(destRobustDirPath));
            // Tenta deletar o diretório pai, só funciona se estiver vazio
            Files.deleteIfExists(Paths.get(destRobustDirPath).getParent());
            System.out.println("\nArquivos e diretórios de demonstração limpos.");
        } catch (IOException e) {
            System.err.println("Erro ao limpar arquivos/diretórios: " + e.getMessage());
        }
    }
}

Tags: JavaNIO FilesClass PathAPI filesystem IOException

Publicado em 7-18 16:08