Come copiare un file con Java

1. Panoramica

In questo articolo, tratteremo i modi comuni di copiare i file in Java.

Innanzitutto, utilizzeremo le API standard IO e NIO.2 e due librerie esterne: commons-io e guava.

2. API IO (prima di JDK7)

Prima di tutto, per copiare un file con l' API java.io , dobbiamo aprire un flusso, scorrere il contenuto e scriverlo su un altro flusso:

@Test public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File("src/test/resources/copiedWithIo.txt"); try ( InputStream in = new BufferedInputStream( new FileInputStream(original)); OutputStream out = new BufferedOutputStream( new FileOutputStream(copied))) { byte[] buffer = new byte[1024]; int lengthRead; while ((lengthRead = in.read(buffer)) > 0) { out.write(buffer, 0, lengthRead); out.flush(); } } assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }

Un bel po 'di lavoro per implementare queste funzionalità di base.

Fortunatamente per noi, Java ha migliorato le sue API principali e abbiamo un modo più semplice per copiare i file utilizzando l' API NIO.2 .

3. NIO.2 API (JDK7)

L'utilizzo di NIO.2 può aumentare notevolmente le prestazioni di copia dei file poiché NIO.2 utilizza punti di ingresso del sistema di livello inferiore.

Diamo uno sguardo più da vicino a come il file Files. Il metodo copy () funziona.

Il metodo copy () ci dà la possibilità di specificare un argomento opzionale che rappresenta un'opzione di copia. Per impostazione predefinita, la copia di file e directory non sovrascriverà quelli esistenti, né copierà gli attributi dei file.

Questo comportamento può essere modificato utilizzando le seguenti opzioni di copia:

  • REPLACE_EXISTING: sostituisci un file se esiste
  • COPY_ATTRIBUTES - copia i metadati nel nuovo file
  • NOFOLLOW_LINKS - non dovrebbe seguire link simbolici

La classe NIO.2 Files fornisce una serie di metodi copy () sovraccaricati per copiare file e directory all'interno del file system.

Diamo un'occhiata a un esempio che utilizza copy () con due argomenti Path :

@Test public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); Path originalPath = original.toPath(); Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); assertThat(copied).exists(); assertThat(Files.readAllLines(originalPath) .equals(Files.readAllLines(copied))); }

Notare che le copie di directory sono superficiali , il che significa che i file e le sottodirectory all'interno della directory non vengono copiati.

4. Apache Commons IO

Un altro modo comune per copiare un file con Java è utilizzare la libreria commons-io .

Innanzitutto, dobbiamo aggiungere la dipendenza:

 commons-io commons-io 2.6 

L'ultima versione può essere scaricata da Maven Central.

Quindi, per copiare un file, è sufficiente utilizzare il metodo copyFile () definito nella classe FileUtils . Il metodo accetta un file di origine e uno di destinazione.

Diamo un'occhiata a un test JUnit utilizzando il metodo copyFile () :

@Test public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File( "src/test/resources/copiedWithApacheCommons.txt"); FileUtils.copyFile(original, copied); assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }

5. Guava

Infine, daremo un'occhiata alla libreria Guava di Google.

Di nuovo, se vogliamo usare Guava , dobbiamo includere la dipendenza:

 com.google.guava guava 23.0 

L'ultima versione può essere trovata su Maven Central.

Ed ecco il modo di Guava di copiare un file:

@Test public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { File copied = new File("src/test/resources/copiedWithGuava.txt"); com.google.common.io.Files.copy(original, copied); assertThat(copied).exists(); assertThat(Files.readAllLines(original.toPath()) .equals(Files.readAllLines(copied.toPath()))); }

6. Conclusione

In questo articolo, abbiamo esplorato i modi più comuni per copiare un file in Java.

L'implementazione completa di questo articolo può essere trovata su Github.