Solución:
Entonces, después de mucha investigación, finalmente me di cuenta de que había algo mal con los últimos bits de datos que se transmitieron en el evento de ‘datos’. Según tengo entendido, parece ser un error en la implementación del flujo de lectura. Pude solucionar este problema utilizando las funciones más simplistas (abrir, fstat, leer) en la biblioteca SSH2. Esta solución me funciona. Quería compartir la solución si alguien más se encuentra con el mismo problema.
Código de trabajo:
sftp.open(config.ftpPath + "https://foroayuda.es/" + m_fileName, "r", function(err, fd) {
sftp.fstat(fd, function(err, stats) {
var bufferSize = stats.size,
chunkSize = 16384,
buffer = new Buffer(bufferSize),
bytesRead = 0,
errorOccured = false;
while (bytesRead < bufferSize && !errorOccured) {
if ((bytesRead + chunkSize) > bufferSize) {
chunkSize = (bufferSize - bytesRead);
}
sftp.read(fd, buffer, bytesRead, chunkSize, bytesRead, callbackFunc);
bytesRead += chunkSize;
}
var totalBytesRead = 0;
function callbackFunc(err, bytesRead, buf, pos) {
if(err) {
writeToErrorLog("downloadFile(): Error retrieving the file.");
errorOccured = true;
sftp.close(fd);
}
totalBytesRead += bytesRead;
data.push(buf);
if(totalBytesRead === bufferSize) {
m_fileBuffer = Buffer.concat(data);
writeToLog("downloadFile(): File saved to buffer.");
sftp.close(fd);
m_eventEmitter.emit(' downloadFile_Completed ');
}
}
})
});
Si el tamaño del byte (o el tamaño del fragmento) no es obligatorio y solo necesita obtener el archivo, supongo que hay una forma mucho mejor, más ligera y rápida (sí … ¡la forma de nodejs!). Así es como utilizo para copiar un archivo:
function getFile(remoteFile, localFile) {
conn.on('ready', function () {
conn.sftp(function (err, sftp) {
if (err) throw err;
var rstream = sftp.createReadStream(remoteFile);
var wstream = fs.createWriteStream(localFile);
rstream.pipe(wstream);
rstream.on('error', function (err) { // To handle remote file issues
console.log(err.message);
conn.end();
rstream.destroy();
wstream.destroy();
});
rstream.on('end', function () {
conn.end();
});
wstream.on('finish', function () {
console.log(`${remoteFile} has successfully download to ${localFile}!`);
});
});
}).connect(m_ssh2Credentials);
}
Como alternativa, también puede probar sftp.fastGet()
que usa lecturas paralelas para traer el archivo rápidamente. fastGet()
le proporciona una forma de mostrar el progreso de la descarga (si lo desea), además de proporcionar una forma de configurar el número de lecturas paralelas y el tamaño del fragmento. Para saber más, abra este documento de SFTPStream y busque fastGet
.
Aquí hay un código muy rápido:
sftp.fastGet(remoteFile, localFile, function (err) {
if (err) throw err;
console.log(`${remoteFile} has successfully download to ${localFile}!`);
}
Hola!