Cómo copiar un archivo en Java

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *