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
LinkOptionfor 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_LINKSfor 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());
}
}
}