CodeGym /Cursos /JAVA 25 SELF /Copiando e movendo arquivos e pastas

Copiando e movendo arquivos e pastas

JAVA 25 SELF
Nível 40 , Lição 1
Disponível

1. Cópia de arquivos

Método Files.copy: sintaxe básica

Em Java, para copiar arquivos e pastas utiliza-se o método estático Files.copy do pacote java.nio.file. Já o vimos antes, mas agora vamos estudá-lo em mais detalhes. Sintaxe básica de Files.copy:

Files.copy(Path source, Path target, CopyOption... options)
  • source — caminho para o arquivo ou pasta de origem.
  • target — caminho para onde copiar.
  • options — opções adicionais (por exemplo, permitir sobrescrita).

Exemplo simples

Vamos copiar o arquivo "input.txt" do diretório atual para a pasta "backup" com o nome "input_backup.txt":

import java.nio.file.*;

public class CopyExample {
    public static void main(String[] args) throws Exception {
        Path source = Path.of("input.txt");
        Path target = Path.of("backup/input_backup.txt");

        Files.copy(source, target);
        System.out.println("Arquivo copiado!");
    }
}

Pontos importantes:

  • Se o arquivo de destino já existir, será lançada a exceção FileAlreadyExistsException.
  • Se a pasta "backup" não existir, o método lançará um erro — a pasta deve ser criada previamente!

Cópia com sobrescrita

Para permitir sobrescrever o arquivo, use a opção StandardCopyOption.REPLACE_EXISTING:

Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

Tabela: principais opções de cópia

Opção Descrição
StandardCopyOption.REPLACE_EXISTING
Sobrescrever o arquivo se ele já existir
StandardCopyOption.COPY_ATTRIBUTES
Copiar atributos (data de criação etc.)
StandardCopyOption.ATOMIC_MOVE
Movimentação atômica (usada apenas com move)

Copiar arquivo para outra pasta

Antes de copiar o arquivo, certifique-se de que a pasta de destino exista:

Path targetDir = Path.of("backup");
if (!Files.exists(targetDir)) {
    Files.createDirectory(targetDir);
}
Files.copy(source, targetDir.resolve("input_backup.txt"), StandardCopyOption.REPLACE_EXISTING);

Cópia de diretórios: pegadinha

O método Files.copy consegue copiar pastas apenas como uma “casca vazia” — o conteúdo (arquivos e subpastas) não é copiado! Se você tentar copiar uma pasta com arquivos, obterá apenas um diretório vazio. Para copiar diretórios inteiros com conteúdo, será necessário percorrer recursivamente e copiar manualmente cada arquivo (voltaremos a isso em aulas seguintes).

Exemplo: copiar um arquivo de uma pasta para outra

Path source = Path.of("data/report.txt");
Path target = Path.of("backup/report.txt");

Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

Tratamento de erros ao copiar

A cópia pode falhar por vários motivos: sem acesso, arquivo em uso, falta de espaço, arquivo já existe etc. É melhor sempre usar try-catch:

try {
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Cópia bem-sucedida!");
} catch (FileAlreadyExistsException e) {
    System.out.println("O arquivo já existe: " + target);
} catch (IOException e) {
    System.out.println("Erro de E/S: " + e.getMessage());
}

2. Movimentação de arquivos e pastas

Método Files.move: sintaxe

A movimentação de arquivos e pastas é feita com o método:

Files.move(Path source, Path target, CopyOption... options)

Onde source — caminho do arquivo (de onde movemos), target — para onde queremos colocar o arquivo ou a pasta, options — configurações adicionais (por exemplo, substituição de um arquivo existente).

Aliás, mover não é apenas “realocar” o arquivo, mas também uma forma de renomear (se apenas o nome mudar). E, se já houver um arquivo com esse nome na pasta de destino, será lançada uma exceção, a menos que você indique a opção REPLACE_EXISTING.

Exemplo: mover um arquivo para outra pasta

Path source = Path.of("data/report.txt");
Path target = Path.of("archive/report.txt");

Files.move(source, target);
System.out.println("Arquivo movido!");

Mover substituindo um arquivo existente

Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

Mover pasta

Path oldDir = Path.of("data/old_reports");
Path newDir = Path.of("archive/old_reports");

Files.move(oldDir, newDir);

A pasta inteira, incluindo arquivos e subpastas, será movida para o novo local.
Mas se já existir no destino uma pasta com esse nome — você receberá um erro.

Mover entre sistemas de arquivos diferentes

Se você mover um arquivo entre discos diferentes (por exemplo, de "C:" para "D:"), por baixo dos panos ocorrerá uma cópia seguida da exclusão do arquivo original. Se a operação não for suportada como atômica, pode ser lançada a exceção AtomicMoveNotSupportedException.

Diferença entre move e copy

  • copy — o arquivo/pasta de origem permanece no lugar e surge uma cópia.
  • move — o arquivo/pasta de origem desaparece e fica apenas o novo objeto.

3. Renomeando arquivos e pastas

No Java não há um método separado “renomear arquivo”. Renomear é um caso particular de mover: você informa um novo caminho com outro nome no mesmo diretório.

Exemplo: renomear um arquivo

Suponha que temos o arquivo "report.txt" e queremos renomeá-lo para "report_old.txt" na mesma pasta:

Path dir = Path.of("data");
Path oldName = dir.resolve("report.txt");
Path newName = dir.resolve("report_old.txt");

Files.move(oldName, newName);
System.out.println("Arquivo renomeado!");

Detalhes importantes

Se no diretório de destino já existir um arquivo ou pasta com o nome informado, o método lançará uma exceção. Para contornar isso e permitir a substituição, pode-se usar a opção StandardCopyOption.REPLACE_EXISTING.

Exemplo:

Path source = Paths.get("old_name.txt");
Path target = Paths.get("new_name.txt");

// Renomear o arquivo; se já existir — substituir
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

Neste exemplo, o arquivo "old_name.txt" será renomeado para "new_name.txt". Se já houver um arquivo com esse nome na pasta, ele será sobrescrito.

Renomear pasta

Path oldDir = Path.of("data/old_reports");
Path newDir = Path.of("data/archived_reports");

Files.move(oldDir, newDir);
System.out.println("Pasta renomeada!");

4. Tratamento de erros ao copiar, mover e renomear

Trabalhar com o sistema de arquivos sempre traz risco de situações inesperadas. Aqui estão os problemas mais comuns:

O arquivo já existe.
Exceção: FileAlreadyExistsException. Solução: use REPLACE_EXISTING se quiser sobrescrever.

Arquivo ou pasta em uso por outro processo.
Exceção: IOException. Por exemplo, o arquivo está aberto em outro programa.

Sem acesso ao arquivo ou à pasta.
Exceção: AccessDeniedException. Problema com permissões do usuário.

Movimentação entre sistemas de arquivos diferentes.
Exceção: AtomicMoveNotSupportedException. Nem todos os sistemas de arquivos suportam movimentação atômica.

A pasta de destino não existe.
Para copiar/mover, certifique-se de que a pasta de destino foi criada previamente!

Exemplo de tratamento de erros

try {
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (FileAlreadyExistsException e) {
    System.out.println("O arquivo de destino já existe: " + target);
} catch (AtomicMoveNotSupportedException e) {
    System.out.println("Movimentação atômica não é suportada: " + e.getMessage());
} catch (IOException e) {
    System.out.println("Erro ao mover: " + e.getMessage());
}

5. Recomendações práticas

Verificar a existência do arquivo/pasta de destino

Antes de copiar ou mover, sempre vale a pena verificar se o caminho de destino não está ocupado:

if (Files.exists(target)) {
    System.out.println("O arquivo já existe; não iremos sobrescrever.");
} else {
    Files.copy(source, target);
}

Uso de arquivos temporários para operações seguras

Em operações complexas (por exemplo, atualização de arquivos importantes) costuma-se usar arquivos temporários — primeiro copia-se para um arquivo temporário e depois substitui-se o principal:

Path temp = Path.of("data/report.tmp");
Files.copy(source, temp, StandardCopyOption.REPLACE_EXISTING);
Files.move(temp, target, StandardCopyOption.REPLACE_EXISTING);

Essa abordagem minimiza o risco de perda de dados em caso de falhas.

Exemplo: fazer backup do arquivo antes de substituir

Path file = Path.of("data/report.txt");
Path backup = Path.of("data/report_backup.txt");

if (Files.exists(file)) {
    Files.copy(file, backup, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Backup criado.");
}

6. Tabela: principais métodos e opções

Operação Método Java NIO Observações
Cópia
Files.copy(source, target, ...)
Não copia o conteúdo das pastas!
Movimentação
Files.move(source, target, ...)
Pode ser usado para renomear
Renomear
Files.move(source, target, ...)
Novo caminho no mesmo diretório
Sobrescrita
StandardCopyOption.REPLACE_EXISTING
Sobrescreve o arquivo/pasta de destino
Verificação
Files.exists(path)
Verifica a existência de arquivo/pasta

7. Erros comuns ao copiar, mover e renomear arquivos

Erro nº 1: tentar copiar um arquivo para uma pasta inexistente. Se o diretório de destino não tiver sido criado, você receberá NoSuchFileException. Solução: criar a pasta antecipadamente com Files.createDirectories.

Erro nº 2: tentar copiar a pasta inteira com Files.copy. O método copiará apenas a “casca vazia”, e não o conteúdo. Para copiar tudo, é necessário um percurso recursivo.

Erro nº 3: não tratar o caso de arquivo existente. Se não passar REPLACE_EXISTING e o arquivo já existir, será lançada uma exceção. É melhor tratar esse caso explicitamente.

Erro nº 4: tentar renomear quando já existe um arquivo com o novo nome. De forma análoga, você receberá FileAlreadyExistsException. Antes de renomear, pode-se verificar a existência do arquivo.

Erro nº 5: movimentação entre sistemas de arquivos diferentes. Às vezes a operação não é suportada de forma “atômica” e é lançada AtomicMoveNotSupportedException. Nesse caso, use uma movimentação comum sem atomicidade.

Erro nº 6: falta de permissões ou arquivo bloqueado. Se o arquivo estiver aberto em outro programa ou não houver permissões de leitura/gravação, você receberá AccessDeniedException ou IOException. Sempre trate tais exceções.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION