Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

239
Vistas
El nodo FTP no ejecuta la devolución de llamada `once('close')` cuando la descarga del archivo es grande

Tengo un método para descargar archivos desde un servidor FTP y funciona bien en archivos más pequeños, pero cuando lo uso para descargar un archivo de ~5 GB de tamaño de tipo zip, lo descarga, pero luego no hace nada. Cuando alcanza el 100% de la descarga, el script no continúa. ¿Debo esperar si realmente está haciendo algo en segundo plano después de que se complete la descarga? ¿Hay límite de tamaño de archivo?

 const FTP = require('ftp')

que se puede encontrar en npm

 downloadFile: params => { return new Promise((resolve, reject) => { let ftpClient = new FTP() let total = params.state.fileSize let progress = 0 ftpClient.on('ready', _ => { console.log(`Downloading ${params.targetedFile} ...`); ftpClient.get(params.targetedFile, (err, stream) => { if (err) reject(err) stream.on('data', buffer => { progress += buffer.length process.stdout.write(`Progress: ${(progress/total*100).toFixed(2)}% (${progress}/${total}) \r`) }) stream.once('close', _ => { ftpClient.end() console.log(`Saved downloaded file to ${params.localDir}`); resolve(params.localDir) }) stream.pipe(fs.createWriteStream(params.localDir)) }) }) ftpClient.connect(params.auth) }) }

Básicamente, la devolución de llamada para stream.once('close', ...) no se ejecuta cuando se descarga un archivo grande. Y se ejecuta para un archivo más pequeño del mismo tipo.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Le recomiendo que maneje el evento de cerrar el flujo de escritura.

La razón es simple: leemos desde el flujo de lectura de ftp y canalizamos para escribir el flujo, todo está bien, cuando el archivo se cierra con éxito.

Así que código:

 downloadFile: params => { return new Promise((resolve, reject) => { let ftpClient = new FTP() let total = params.state.fileSize let progress = 0 ftpClient.on('ready', _ => { console.log(`Downloading ${params.targetedFile} ...`); ftpClient.get(params.targetedFile, (err, stream) => { if (err) { ftpClient.end(); return reject(err); } stream.on('data', buffer => { progress += buffer.length process.stdout.write(`Progress: ${(progress/total*100).toFixed(2)}% (${progress}/${total}) \r`) }); // opening writeStream to file let finished = false; const writeStream = fs.createWriteStream(params.localDir); writeStream.on('finish', (result) => { // handling finish finished = true; ftpClient.end(); console.log(`Finish triggered ${params.localDir}`); console.log(result); resolve(params.localDir); }); writeStream.on('close', (result) => { // handling close ftpClient.end(); console.log(`Close triggered ${params.localDir}`); console.log(result); resolve(params.localDir); }) // piping readStream to writeStream stream.pipe(writeStream); }) }) ftpClient.connect(params.auth) }) }
over 4 years ago · Santiago Trujillo Denunciar

0

Este código podría darle una idea de cómo manejar esto de una manera un poco rara.

Básicamente, este método le permite descargar archivos del servidor FTP y guardarlos en el sistema de archivos local. Muestra el progreso actual complete_percentage% (current/total) en una sola línea. Al finalizar, resuelve la promesa, devuelve la ruta al archivo local, la misma que pasó como parámetro.

 /** * @name downloadFile * @desc downloads file from FTP server * @param params, Object of params * @prop auth: object, or null, authorization params * @prop targetedFile: {String} filename eg data.txt * @prop localDir: {String} filename on local disk * @prop state: {Object} fileinfo object, {Int} .fileSize property is required * @return Promise, resolves given localDir */ downloadFile: params => { return new Promise((resolve, reject) => { // validate param types if(typeof params.auth !== 'object' || typeof params.targetedFile !== 'string' || typeof params.localDir !== 'string' || typeof params.state !== 'object' || typeof params.state.fileSize !== 'number' ) throw new Error('You are either missing properties or passed wrong types') // initialize let ftpClient = new FTP() let total = params.state.fileSize let progress = 0 // ftpClient.on('ready', _ => { console.log(`Downloading ${params.targetedFile} ...`) // get file ftpClient.get(params.targetedFile, (err, stream) => { if (err){ ftpClient.end() return reject(err) } // upon data receive stream.on('data', buffer => { progress += buffer.length // if progress is complete if(progress === total){ // start checking if local filesize matches server filesize let interval = setInterval(_ => { if(fs.statSync(params.localDir).size === total){ console.log(`Downloading file complete. Location: ${params.localDir}`); clearInterval(interval) ftpClient.end() resolve(params.localDir) } }) } // show current progress in percentages and bytes process.stdout.write(`Progress: ${(progress/total*100).toFixed(2)}% (${progress}/${total}) \r`) }) // pipe writestream to filesystem to write these bytes stream.pipe(fs.createWriteStream(params.localDir)) }) }) ftpClient.connect(params.auth) })//promise }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda