Cómo trabajar con archivos zip en Node.js

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Configuración del proyecto
  • Paso 2: creación de un archivo ZIP
  • Paso 3: Listado de archivos en un archivo ZIP
  • Paso 4: Agregar un archivo a un archivo existente
  • Paso 5: extracción de un archivo zip
  • Conclusión
  • El autor seleccionó Open Sourcing Mental Illness para recibir una donación como parte del programa Write for DOnations .

    Introducción

    Trabajar con archivos es una de las tareas más habituales entre los desarrolladores. A medida que los archivos aumentan de tamaño, comienzan a ocupar un espacio significativo en el disco duro. Tarde o temprano, es posible que deba transferir los archivos a otros servidores o cargar varios archivos desde su máquina local a diferentes plataformas. Algunas de estas plataformas tienen límites de tamaño de archivo y no aceptan archivos grandes. Para solucionar esto, puede agrupar los archivos en un solo archivo ZIP. Un archivo ZIP es un formato de archivo que empaqueta y comprime archivos con el algoritmo de compresión sin pérdida . El algoritmo puede reconstruir los datos sin ninguna pérdida de datos. En Node.js , puede usar el adm-zipmódulo para crear y leer archivos ZIP.

    En este tutorial, utilizará adm-zipel módulo para comprimir, leer y descomprimir archivos. Primero, combinará varios archivos en un archivo ZIP utilizando adm-zip. Luego, enumerará el contenido del archivo ZIP. Después de eso, agregará un archivo a un archivo ZIP existente y, finalmente, extraerá un archivo ZIP en un directorio.

    Prerrequisitos

    Para seguir este tutorial, necesitarás:

    • Node.js instalado en su entorno local o de servidor. Siga Cómo instalar Node.js y crear un entorno de desarrollo local para instalar Node.js.

    • Conocimiento de cómo escribir un programa Node.js, consulte Cómo escribir y ejecutar su primer programa en Node.js.

    • Un conocimiento básico de la programación asincrónica en JavaScript. Visite nuestro tutorial Comprensión del bucle de eventos, las devoluciones de llamadas, las promesas y Async/Await en JavaScript para aprender los conceptos básicos.

    • Conocimiento de cómo trabajar con archivos en Node.js. Consulta el tutorial Cómo trabajar con archivos usando el módulo fs en Node.js para repasar cómo trabajar con archivos.

    Paso 1: Configuración del proyecto

    En este paso, creará el directorio para su proyecto y lo instalará adm-zipcomo una dependencia. Este directorio es donde guardará los archivos de programa. También creará otro directorio que contenga archivos de texto y una imagen. Archivará este directorio en la siguiente sección.

    Crea un directorio llamado zip_appcon el siguiente comando:

    1. mkdir zip_app

    Navegue hasta el directorio recién creado con el cdcomando:

    1. cd zip_app

    Dentro del directorio, crea un package.jsonarchivo para administrar las dependencias del proyecto:

    1. npm init -y

    La -yopción crea un package.jsonarchivo predeterminado.

    A continuación, instale adm-zipcon el npm installcomando:

    1. npm install adm-zip

    Después de ejecutar el comando, npmse instalará adm-zipy actualizará el package.jsonarchivo.

    A continuación, crea un directorio llamado testy muévete a él:

    1. mkdir test cd test

    En este directorio, creará tres archivos de texto y descargará una imagen. Los tres archivos se rellenarán con contenido ficticio para aumentar su tamaño. Esto ayudará a demostrar la compresión ZIP cuando archive este directorio.

    Crea un archivo file1.txty rellénalo con contenido ficticio utilizando el siguiente comando:

    1. yes "dummy content" | head -n 100000 file1.txt

    El yescomando registra la cadena dummy contentrepetidamente. Con el comando pipe |, envía la salida del yescomando para que se use como entrada para el headcomando. El headcomando imprime parte de la entrada dada en la salida estándar. La -nopción especifica la cantidad de líneas que se deben escribir en la salida estándar. Finalmente, redirige la headsalida a un nuevo archivo file1.txtusando .

    Cree un segundo archivo con la cadena “contenido ficticio” repetida 300.000 líneas:

    1. yes "dummy content" | head -n 300000 file2.txt

    Crea otro archivo con la dummy contentcadena repetida 600.000 líneas:

    1. yes "dummy content" | head -n 600000 file3.txt

    Por último, descargue una imagen en el directorio usando curl:

    1. curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/underwater.png

    Regrese al directorio principal del proyecto con el siguiente comando:

    1. cd ..

    Te moverá ..al directorio principal, que es zip_app.

    Ya ha creado el directorio del proyecto, ha instalado adm-zipy ha creado un directorio con archivos para archivar. En el siguiente paso, archivará un directorio utilizando el adm-zipmódulo.

    Paso 2: creación de un archivo ZIP

    En este paso, utilizarás adm-zippara comprimir y archivar el directorio que creaste en la sección anterior.

    Para archivar el directorio, deberá importar el adm-zipmódulo y utilizar el addLocalFolder()método del módulo para agregar el directorio al adm-zipobjeto ZIP del módulo. Luego, utilizará el writeZip()método del módulo para guardar el archivo en su sistema local.

    Cree y abra un nuevo archivo createArchive.jsen su editor de texto preferido. Este tutorial utiliza nano, un editor de texto de línea de comandos:

    1. nano createArchive.js

    A continuación, solicita en el adm-zipmódulo de tu createArchive.jsarchivo:

    zip_app/createArchive.js

    const AdmZip = require("adm-zip");

    El adm-zipmódulo proporciona una clase que contiene métodos para crear archivos ZIP.

    Dado que es habitual encontrar archivos grandes durante el proceso de archivado, es posible que acabes bloqueando el hilo principal hasta que se guarde el archivo ZIP. Para escribir código sin bloqueo, definirás una función asincrónica para crear y guardar un archivo ZIP.

    En su createArchive.jsarchivo, agregue el siguiente código resaltado:

    zip_app/createArchive.js

    const AdmZip = require("adm-zip");async function createZipArchive() {  const zip = new AdmZip();  const outputFile = "test.zip";  zip.addLocalFolder("./test");  zip.writeZip(outputFile);  console.log(`Created ${outputFile} successfully`);}createZipArchive();

    createZipArchivees una función asincrónica que crea un archivo ZIP a partir de un directorio determinado. Lo que la hace asincrónica es la asyncpalabra clave que definió antes de la etiqueta de la función. Dentro de la función, crea una instancia del adm-zipmódulo, que proporciona métodos que puede usar para leer y crear archivos. Cuando crea una instancia, adm-zipcrea un ZIP en memoria donde puede agregar archivos o directorios.

    A continuación, se define el nombre del archivo y se almacena en la outputDirvariable. Para agregar el testdirectorio al archivo en memoria, se invoca el addLocalFolder()método from adm-zipcon la ruta del directorio como argumento.

    Una vez que se agrega el directorio, se invoca el writeZip()método from adm-zipcon una variable que contiene el nombre del archivo ZIP. El writeZip()método guarda el archivo en el disco local.

    Una vez hecho esto, invoca console.log()para registrar que el archivo ZIP se ha creado correctamente.

    Finalmente, llama a la createZipArchive()función.

    Antes de ejecutar el archivo, envuelva el código en un bloque try…catch para manejar errores de tiempo de ejecución:

    zip_app/createArchive.js

    const AdmZip = require("adm-zip");async function createZipArchive() {  try {    const zip = new AdmZip();    const outputFile = "test.zip";    zip.addLocalFolder("./test");    zip.writeZip(outputFile);    console.log(`Created ${outputFile} successfully`);  } catch (e) {    console.log(`Something went wrong. ${e}`);  }}createZipArchive();

    Dentro del trybloque, el código intentará crear un archivo ZIP. Si tiene éxito, la createZipArchive()función saldrá y se saltará el catchbloque. Si la creación de un archivo ZIP genera un error, la ejecución saltará al catchbloque y registrará el error en la consola.

    Guarde y salga del archivo nanocon CTRL+X. Presione Enter ypara guardar los cambios y confirme el archivo presionando ENTERen Windows o la RETURNtecla en Mac.

    Ejecute el createArchive.jsarchivo usando el nodecomando:

    1. node createArchive.js

    Recibirás el siguiente resultado:

    OutputCreated test.zip successfully

    Enumere el contenido del directorio para ver si se ha creado el archivo ZIP:

    1. ls

    Recibirá la siguiente salida que muestra el archivo entre los contenidos:

    OutputcreateArchive.js  node_modules  package-lock.jsonpackage.json  test  test.zip

    Con la confirmación de que se ha creado el archivo ZIP, comparará el archivo ZIP y el testtamaño del archivo del directorio para ver si la compresión funciona.

    Compruebe el testtamaño del directorio usando el ducomando:

    1. du -h test

    La -hbandera indica duque se debe mostrar el tamaño del directorio en un formato legible para humanos.

    Después de ejecutar el comando, recibirá el siguiente resultado:

    Output15Mtest

    A continuación, compruebe el test.ziptamaño del archivo comprimido:

    1. du -h test.zip

    El ducomando registra la siguiente salida:

    Output760Ktest.zip

    Como puede ver, al crear el archivo ZIP, el tamaño del directorio se redujo de 15 megabytes (MB) a 760 kilobytes (KB), lo que supone una gran diferencia. El archivo ZIP es más portátil y de menor tamaño.

    Ahora que ha creado un archivo ZIP, está listo para enumerar el contenido en un archivo ZIP.

    Paso 3: Listado de archivos en un archivo ZIP

    En este paso, leerá y listará todos los archivos en un archivo ZIP usando adm-zip. Para ello, creará una instancia del adm-zipmódulo con la ruta de su archivo ZIP. Luego, llamará al getEntries()método del módulo que devuelve una matriz de objetos. Cada objeto contiene información importante sobre un elemento en el archivo ZIP. Para listar los archivos, iterará sobre la matriz y accederá al nombre de archivo desde el objeto y lo registrará en la consola.

    Crea y abre readArchive.jsen tu editor de texto favorito:

    1. nano readArchive.js

    En su readArchive.js, agregue el siguiente código para leer y enumerar el contenido de un archivo ZIP:

    zip_app/readArchive.js

    const AdmZip = require("adm-zip");async function readZipArchive(filepath) {  try {    const zip = new AdmZip(filepath);    for (const zipEntry of zip.getEntries()) {      console.log(zipEntry.toString());    }  } catch (e) {    console.log(`Something went wrong. ${e}`);  }}readZipArchive("./test.zip");

    Primero, necesitas estar en el adm-zipmódulo.

    A continuación, se define la readZipArchive()función, que es una función asincrónica. Dentro de la función, se crea una instancia de adm-zipcon la ruta del archivo ZIP que se desea leer. La ruta del archivo se proporciona mediante el filepathparámetro. adm-zipleerá el archivo y lo analizará.

    Después de leer el archivo, se define una for....ofdeclaración que itera sobre los objetos de una matriz que el getEntries()método adm-zipdevuelve cuando se invoca. En cada iteración, el objeto se asigna a la zipEntryvariable. Dentro del bucle, se convierte el objeto en una cadena que representa el objeto mediante el toString()método Node.js y, luego, se registra en la consola mediante el console.log()método.

    Finalmente, invoca la readZipArchive()función con la ruta del archivo ZIP como argumento.

    Guarde y salga de su archivo, luego ejecute el archivo con el siguiente comando:

    1. node readArchive.js

    Obtendrá un resultado similar al siguiente (editado para abreviar):

    Output{"entryName": "file1.txt","name": "file1.txt","comment": "","isDirectory": false,"header": {...},"compressedData": "27547 bytes buffer","data": "null"}...

    La consola registrará cuatro objetos. Los demás objetos se han eliminado para que el tutorial sea breve.

    Cada archivo del archivo se representa con un objeto similar al que se muestra en la salida anterior. Para obtener el nombre de archivo de cada archivo, debe acceder a la namepropiedad.

    En su readArchive.jsarchivo, agregue el siguiente código resaltado para acceder a cada nombre de archivo:

    zip_app/readArchive.js

    const AdmZip = require("adm-zip");async function readZipArchive(filepath) {  try {    const zip = new AdmZip(filepath);    for (const zipEntry of zip.getEntries()) {      console.log(zipEntry.name);    }  } catch (e) {    console.log(`Something went wrong. ${e}`);  }}readZipArchive("./test.zip");

    Guarde y salga del editor de texto. Ahora, vuelva a ejecutar el archivo con el nodecomando:

    1. node readArchive.js

    Al ejecutar el archivo se obtiene el siguiente resultado:

    Outputfile1.txtfile2.txtfile3.txtunderwater.png

    La salida ahora registra el nombre de archivo de cada archivo en el archivo ZIP.

    Ahora puede leer y enumerar cada archivo en un archivo ZIP. En la siguiente sección, agregará un archivo a un archivo ZIP existente.

    Paso 4: Agregar un archivo a un archivo existente

    En este paso, creará un archivo y lo agregará al archivo ZIP que creó anteriormente sin extraerlo. Primero, leerá el archivo ZIP creando una adm-zipinstancia. En segundo lugar, invocará el addFile()método del módulo para agregar el archivo al ZIP. Por último, guardará el archivo ZIP en el sistema local.

    Crea otro archivo file4.txtcon contenido ficticio repetido 600.000 líneas:

    1. yes "dummy content" | head -n 600000 file4.txt

    Crea y abre updateArchive.jsen tu editor de texto:

    1. nano updateArchive.js

    Requerir en el adm-zipmódulo y el fsmódulo que le permite trabajar con archivos en su updateArchive.jsarchivo:

    const AdmZip = require("adm-zip");const fs = require("fs").promises;

    Necesita la versión basada en promesas del fsmódulo, que le permite escribir código asincrónico. Cuando invoca un fsmétodo, devolverá una promesa.

    A continuación, en su updateArchive.jsarchivo, agregue el siguiente código resaltado para agregar un nuevo archivo al archivo ZIP:

    zip_app/updateArchive.js

    const AdmZip = require("adm-zip");const fs = require("fs").promises;async function updateZipArchive(filepath) {  try {    const zip = new AdmZip(filepath);    content = await fs.readFile("./file4.txt");    zip.addFile("file4.txt", content);    zip.writeZip(filepath);    console.log(`Updated ${filepath} successfully`);  } catch (e) {    console.log(`Something went wrong. ${e}`);  }}updateZipArchive("./test.zip");

    updateZipArchivees una función asincrónica que lee un archivo en el sistema de archivos y lo agrega a un ZIP existente. En la función, se crea una instancia de adm-zipcon la ruta del archivo ZIP como filepathparámetro. A continuación, se invoca el método fsdel módulo readFile()para leer el archivo en el sistema de archivos. El readFile()método devuelve una promesa, que se resuelve con la awaitpalabra clave ( awaites válida solo en funciones asincrónicas). Una vez resuelta, el método devuelve un objeto de búfer , que contiene el contenido del archivo.

    A continuación, invoca el addFile()método from adm-zip. El método acepta dos argumentos. El primer argumento es el nombre del archivo que deseas agregar al archivo y el segundo argumento es el objeto de búfer que contiene el contenido del archivo que readFile()lee el método.

    Luego, invoca el método adm-zipdel módulo writeZip()para guardar y escribir los cambios nuevos en el archivo ZIP. Una vez hecho esto, llama al console.log()método para registrar un mensaje de éxito.

    Finalmente, invoca la updateZipArchive()función con la ruta del archivo Zip como argumento.

    Guarde y salga del archivo. Ejecute el updateArchive.jsarchivo con el siguiente comando:

    1. node updateArchive.js

    Verás un resultado como este:

    OutputUpdated ./test.zip successfully

    Ahora, confirme que el archivo ZIP contiene el nuevo archivo. Ejecute el readArchive.jsarchivo para enumerar el contenido del archivo ZIP con el siguiente comando:

    1. node readArchive.js

    Recibirás el siguiente resultado:

    file1.txtfile2.txtfile3.txtfile4.txtunderwater.png

    Esto confirma que el archivo se ha agregado al ZIP.

    Ahora que puedes agregar un archivo a un archivo existente, extraerás el archivo en la siguiente sección.

    Paso 5: extracción de un archivo zip

    En este paso, leerá y extraerá todo el contenido de un archivo ZIP en un directorio. Para extraer un archivo ZIP, deberá crear una instancia adm-zipcon la ruta del archivo. Después, invocará el extractAllTo()método del módulo con el nombre del directorio en el que desea que residan los contenidos ZIP extraídos.

    Crea y abre extractArchive.jsen tu editor de texto:

    1. nano extractArchive.js

    Requerir en el adm-zipmódulo y el pathmódulo en su extractArchive.jsarchivo:

    zip_app/extractArchive.js

    const AdmZip = require("adm-zip");const path = require("path");

    El pathmódulo proporciona métodos útiles para tratar con rutas de archivos.

    Aún en su extractArchive.jsarchivo, agregue el siguiente código resaltado para extraer un archivo:

    zip_app/extractArchive.js

    const AdmZip = require("adm-zip");const path = require("path");async function extractArchive(filepath) {  try {    const zip = new AdmZip(filepath);    const outputDir = `${path.parse(filepath).name}_extracted`;    zip.extractAllTo(outputDir);    console.log(`Extracted to "${outputDir}" successfully`);  } catch (e) {    console.log(`Something went wrong. ${e}`);  }}extractArchive("./test.zip");

    extractArchive()es una función asincrónica que toma un parámetro que contiene la ruta del archivo ZIP. Dentro de la función, se crea una instancia adm-zipcon la ruta del archivo ZIP proporcionada por el filepathparámetro.

    A continuación, se define un literal de plantilla . Dentro del marcador de posición del literal de plantilla ( ${}), se invoca el parse()método desde el pathmódulo con la ruta del archivo. El parse()método devuelve un objeto. Para obtener el nombre del archivo ZIP sin la extensión del archivo, se añade la namepropiedad al objeto que parse()devuelve el método. Una vez que se devuelve el nombre del archivo, el literal de plantilla interpola el valor con la _extractedcadena. Luego, el valor se almacena en la outputDirvariable. Este será el nombre del directorio extraído.

    A continuación, invoca el método adm-zipdel módulo extractAllTocon el nombre del directorio almacenado outputDirpara extraer el contenido del directorio. Después de eso, invoca console.log()para registrar un mensaje de éxito.

    Finalmente, llama a la extractArchive()función con la ruta del archivo ZIP.

    Guarde el archivo y salga del editor, luego ejecute el extractArchive.jsarchivo con el siguiente comando:

    1. node extractArchive.js

    Recibirá el siguiente resultado:

    OutputExtracted to "test_extracted" successfully

    Confirme que se ha creado el directorio que contiene el contenido ZIP:

    1. ls

    Recibirá el siguiente resultado:

    OutputcreateArchive.js   file4.txt   package-lock.jsonreadArchive.js  test.zip        updateArchive.jsextractArchive.js  node_modules  package.jsontest           test_extracted

    Ahora, navegue hasta el directorio que contiene el contenido extraído:

    1. cd test_extracted

    Enumere el contenido del directorio:

    1. ls

    Recibirá el siguiente resultado:

    Outputfile1.txt  file2.txt  file3.txt  file4.txt  underwater.png

    Ahora puedes ver que el directorio tiene todos los archivos que estaban en el directorio original.

    Ahora ha extraído el contenido del archivo ZIP en un directorio.

    Conclusión

    En este tutorial, creaste un archivo ZIP, enumeraste su contenido, agregaste un nuevo archivo al archivo y extrajiste todo su contenido en un directorio usando adm-zipmodule. Esto servirá como una buena base para trabajar con archivos ZIP en Node.js.

    Para obtener más información sobre adm-zipel módulo, consulte la documentación de adm-zip . Para seguir desarrollando su conocimiento sobre Node.js, consulte la serie Cómo codificar en Node.js

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

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

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion