javascript

Unir archivos con JavaScript

Hoy te voy a enseñar a unir archivos usando el navegador web con JavaScript del lado del cliente para concatenar bytes de archivos y crear un archivo a partir de varias partes. Este script de JavaScript va a permitirte seleccionar varios archivos (con extensión part1, part2, etcétera) para unirlos en uno solo, sin tener que procesar algo en un servidor. Todo el proceso será realizado en el lado del cliente.

Para concatenar varios archivos vamos a usar Uint8Array y Blob. Básicamente vamos a leer el contenido de cada parte como bytes, y agregar ese montón de bytes a un arreglo que finalmente vamos a convertir a Blob.

Unir archivos part con JavaScript en el navegador web

Puedes acceder al unidor de archivos con JavaScript en el siguiente enlace: https://parzibyte.github.io/ejemplos-javascript/unir-archivos/

Unir archivos con JavaScript

El proceso es simple:

  • Leemos una lista de archivos de un input de tipo file, accediendo a la propiedad files, que será un arreglo
  • Creamos un nuevo Uint8Array en donde alojaremos el archivo resultante
  • Recorremos la lista de partes de archivos leyendo su contenido con FileReader y readAsArrayBuffer
  • Cada vez que terminemos de leer el contenido de un archivo invocamos a set en el archivo resultante para “copiar” los bytes del archivo
  • Una vez que terminemos de leer la lista de partes de archivo, creamos un nuevo Blob y lo descargamos con URL.createObjectURL.

Así que el usuario solo debe seleccionar los archivos divididos y el navegador se encargará de unirlos y mostrar el resultado para su descarga.

Código fuente: concatenar archivos en el navegador web

Lo único que necesitamos es un input de tipo file en el lado de HTML:

<input type="file" id="archivos" multiple>

Escuchamos cuando el usuario seleccione uno o más archivos:

const $archivos = document.querySelector("#archivos");
$archivos.addEventListener("change", async () => {
    // Agregar código aquí 
}

Dentro del change creamos el archivo resultante, calculando la longitud previamente. También tratamos de definir el nombre del archivo resultante, ya que la mayoría de archivos divididos tienen el formato nombre_archivo.extensión.partNúmero:

const archivos = $archivos.files;
let nombreSugeridoParaArchivoUnido = "";
let longitudDeArchivoUnidoEnBytes = 0;
for (const archivo of archivos) {
    if (nombreSugeridoParaArchivoUnido === "") {
        nombreSugeridoParaArchivoUnido = archivo.name.substring(0, archivo.name.lastIndexOf("."));
    }
    longitudDeArchivoUnidoEnBytes += archivo.size;
}
const bytesDeArchivoUnido = new Uint8Array(longitudDeArchivoUnidoEnBytes);

Es momento de mostrar la función que lee el contenido del archivo como bytes y lo devuelve usando promesas:

const leerArchivoComoArrayBuffer = (archivo) => {
    return new Promise((resolve, reject) => {
        const lector = new FileReader();
        lector.onerror = (evento) => {
            reject(evento);
        }
        lector.onload = (evento) => {
            resolve(evento.target.result);
        }
        lector.readAsArrayBuffer(archivo);
    });
}

Ahora recorremos la lista de partes de archivos y concatenamos con set en los bytes del archivo unido:

for (const archivo of archivos) {
    const arrayBufferDeArchivoParcial = await leerArchivoComoArrayBuffer(archivo)
    bytesDeArchivoUnido.set(new Uint8Array(arrayBufferDeArchivoParcial), compensacion)
    compensacion += arrayBufferDeArchivoParcial.byteLength;
}

Finalmente lo descargamos:

const a = document.createElement("a");
const url = URL.createObjectURL(new Blob([bytesDeArchivoUnido], {
    type: "application/octet-stream",
}));
a.href = url;
a.download = nombreSugeridoParaArchivoUnido;
a.click();
URL.revokeObjectURL(url);

Poniendo todo junto

El código fuente completo lo dejaré en mi GitHub. Puedes acceder a la demostración y usar el unidor de archivos con JavaScript en el siguiente enlace: https://parzibyte.github.io/ejemplos-javascript/unir-archivos/

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.