1. Información general
En este artículo, cubriremos formas comunes de copiar archivos en Java.
Primero, usaremos las API estándar IO y NIO.2 , y dos bibliotecas externas: commons-io y guava.
2. API IO (antes de JDK7)
En primer lugar, para copiar un archivo con la API java.io , debemos abrir una secuencia, recorrer el contenido y escribirlo en otra secuencia:
@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()))); }
Mucho trabajo para implementar una funcionalidad tan básica.
Afortunadamente para nosotros, Java ha mejorado sus API principales y tenemos una forma más sencilla de copiar archivos utilizando la API NIO.2 .
3. NIO.2 API (JDK7)
El uso de NIO.2 puede aumentar significativamente el rendimiento de la copia de archivos, ya que NIO.2 utiliza puntos de entrada del sistema de nivel inferior.
Echemos un vistazo más de cerca a cómo funciona Files. El método copy () funciona.
El método copy () nos da la capacidad de especificar un argumento opcional que represente una opción de copia. Por defecto, copiar archivos y directorios no sobrescribirá los existentes, ni copiará atributos de archivo.
Este comportamiento se puede cambiar usando las siguientes opciones de copia:
- REPLACE_EXISTING: reemplaza un archivo si existe
- COPY_ATTRIBUTES - copia metadatos al nuevo archivo
- NOFOLLOW_LINKS: no debe seguir enlaces simbólicos
La clase NIO.2 Files proporciona un conjunto de métodos copy () sobrecargados para copiar archivos y directorios dentro del sistema de archivos.
Echemos un vistazo a un ejemplo usando copy () con dos argumentos 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))); }
Tenga en cuenta que las copias de directorio son superficiales , lo que significa que los archivos y subdirectorios dentro del directorio no se copian.
4. Apache Commons IO
Otra forma común de copiar un archivo con Java es utilizando la biblioteca commons-io .
Primero, necesitamos agregar la dependencia:
commons-io commons-io 2.6
La última versión se puede descargar desde Maven Central.
Luego, para copiar un archivo solo necesitamos usar el método copyFile () definido en la clase FileUtils . El método toma un archivo de origen y otro de destino.
Echemos un vistazo a una prueba JUnit usando el método 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. Guayaba
Finalmente, echaremos un vistazo a la biblioteca Guava de Google.
Nuevamente, si queremos usar Guava , necesitamos incluir la dependencia:
com.google.guava guava 23.0
La última versión se puede encontrar en Maven Central.
Y aquí está la forma de Guava de copiar un archivo:
@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. Conclusión
En este artículo, exploramos las formas más comunes de copiar un archivo en Java.
La implementación completa de este artículo se puede encontrar en Github.