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 *