Cómo copiar un archivo en Java

C

Copiar 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 con menos frecuencia.

Aún así, es un concepto fundamental y podría ser útil saber qué opciones tiene el desarrollador cuando necesita copiar un archivo.

Flujos 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 importante refactorización de la plataforma Java y el lanzamiento de Java 1.4 en 2000, el paquete java.nio Fue presentado.

los File El proceso 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 ciclo while y ya no controlamos el tamaño del búfer directamente.

Clase auxiliar de archivos

Junto con Java 7, lanzado en 2011, se agregó una clase auxiliar 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());
}

Echando un vistazo al Documentación API, vemos que es posible proporcionar una opción adicional a la copy() método.

Las siguientes opciones del StandardCopyOption y LinkOption las enumeraciones son compatibles:

  • REMPLAZA EL EXISTENTE – Realiza la copia incluso cuando el archivo de destino ya existe. Si el destino es un vínculo simbólico, se copia el vínculo en sí (y no el destino del vínculo). Si el destino es un directorio que no está vacío, la copia falla con la excepción FileAlreadyExistsException.
  • COPY_ATTRIBUTES – Copia los atributos de archivo asociados con el archivo en el archivo de destino. Los atributos de archivo exactos admitidos dependen del sistema de archivos y de la plataforma, pero la hora de la última modificación se admite en todas las plataformas y se copia en el archivo de destino.
  • NOFOLLOW_LINKS – Indica que no se deben seguir enlaces simbólicos. Si el archivo que se va a copiar es un enlace simbólico, se copia el enlace (y no el destino del enlace).

Apache Commons IO y Google Guava

Estas dos bibliotecas auxiliares muy útiles proporcionan una API muy similar para copiar archivos. El único inconveniente de usar cualquiera de ellos es tener que agregar otro pesado .jar archivo en el proyecto.

Pero si ya está ahí, ¿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 de archivo real?

No se preocupe, ¡lo tenemos cubierto!

private File filenameToFile(String filename) throws IOException {
    return new File(filename);
}

¿Cual deberías utilizar?

Flujos de E / S y Canales son una opción viable para jugar y comprender 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 Guayaba ya está en la lista de dependencias y elija entre una de ellas.

Si no lo son, entonces no debe agregarlos por el bien de este método de utilidad única y usar Java 7 Files clase de ayudante.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad