Breaking

Post Top Ad

Your Ad Spot

martes, 9 de julio de 2019

Cómo copiar un archivo en Java

Copiando archivos en Java

Copiar un archivo o directorio solía ser una tarea de desarrollo típica. Con la introducción de los contenedores Docker y el deseo de máxima inmutabilidad, lo vemos cada vez menos.
Aún así, es un concepto fundamental y puede ser útil saber qué opciones tiene el desarrollador cuando necesita copiar un archivo.

Streams de E / S

Antes de Java 1.5, la forma estándar de copiar un archivo era utilizando flujos de E / S :
private void copyFile(File src, File dest) throws IOException {  
    InputStream inputStream = null;
    OutputStream outputStream = null;
    try {
        inputStream = new FileInputStream(source);
        outputStream = new FileOutputStream(dest);

        // the size of the buffer doesn't have to be exactly 1024 bytes, try playing around with this number and see what effect it will have on the performance
        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = is.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
    } finally {
        is.close();
        os.close();
    }
}

Canales y java.nio.

Con la mayor refactorización de la plataforma Java y la versión Java 1.4 en 2000, java.niose introdujo el paquete .
El Fileproceso de copia comenzó a verse un poco más elegante y delgado:
private void copyFileUsingChannel(File src, File dest) throws IOException {  
    FileChannel sourceChannel = null;
    FileChannel destinationChannel = null;
    try {
        sourceChannel = new FileInputStream(src).getChannel();
        destinationChannel = new FileOutputStream(dest).getChannel();
        destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
       } finally {
           sourceChannel.close();
           destinationChannel.close();
       }
}
La diferencia más notable es que nos deshicimos del bucle while y ya no controlamos directamente el tamaño del búfer.

Archivos de la clase de ayuda

Junto con Java 7, lanzado en 2011, se agregó una clase de ayuda que nos permite copiar archivos en una sola línea de código:
private static void copyFile(File src, File dest) throws IOException {  
    Files.copy(src.toPath(), dest.toPath());
}
Mirando la documentación de la API , vemos que es posible proporcionar una opción adicional al copy()método.
Se admiten las siguientes opciones de la lista StandardCopyOptionLinkOption:
  • REPLACE_EXISTING : realiza la copia incluso cuando el archivo de destino ya existe. Si el objetivo es un enlace simbólico, el enlace en sí se copia (y no el destino del enlace). Si el destino es un directorio no vacío, la copia falla con la excepción FileAlreadyExistsException.
  • COPY_ATTRIBUTES : copia los atributos de archivo asociados con el archivo al archivo de destino. Los atributos de archivo exactos admitidos dependen del sistema de archivos y de la plataforma, pero el último tiempo modificado se admite en todas las plataformas y se copia en el archivo de destino.
  • NOFOLLOW_LINKS : indica que no se deben seguir los enlaces simbólicos. Si el archivo que se va a copiar es un enlace simbólico, el enlace se copia (y no el destino del enlace).

Apache Commons IO y Google Guava

Estas dos bibliotecas de ayuda muy útiles proporcionan una API muy similar para copiar archivos. El único inconveniente de usar cualquiera de ellos es tener que agregar otro .jararchivo pesado en el proyecto.
Pero si ya está allí, ¿por qué no?
private void copyFileApacheCommons(File src, File dest) throws IOException {  
    FileUtils.copyFile(src, dest);
}
private void copyFileGoogleGuava(File src, File dest) throws IOException {  
    Files.copy(src, dest);
}

Prima

Espera, pero, ¿qué tengo una cadena que representa el nombre del archivo y no el objeto File real?
No te preocupes, lo tenemos cubierto!
private File filenameToFile(String filename) throws IOException {  
    return new File(filename);
}

¿Cual deberías usar?

Los flujos y canales de E / S son una opción viable para jugar y entender cómo se ve el proceso desde adentro.
Otro sería si está trabajando en un proyecto heredado con una versión desactualizada de Java, y actualizarlo no es una opción. En todos los demás casos, debe verificar si Apache Commons o Google Guava ya están en la lista de dependencias y elegir entre una de ellas.
Si no lo son, no debe agregarlos por este método de utilidad única y usar la Filesclase auxiliar de Java 7 .

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas