如何使用 NodeJS 和 promise-ftp 修复我的 stream/writing 数据关闭速度非常慢的问题

How to fix my stream/writing data closing really slow with NodeJS and promise-ftp

我必须从 ftp 服务器下载 json 文件。获取文件的速度非常快,但是带有流的 read/writing 关闭速度非常慢。该文件几乎立即出现在我的桌面上,但没有关闭。

我已经尝试过 promise-ftp 并且 ftp。我将我的 nodejs 和节点更新到最新版本,所以我尝试了多个版本。

const getFile = () => {
  return new Promise((resolve, reject) => {
    console.log('getting file.');
    ftp.connect(config)
      .then(function (serverMessage) {
        return ftp.get(remoteFile + '.json');
      }).then(function (stream) {
        return new Promise(function (resolve, reject) {
          stream.once('close', resolve);
          stream.once('error', reject);
          stream.pipe(fs.createWriteStream(`${steamid}.json`));
        });
      }).then(async function () {
        console.log('done editing');
        await ftp.end();
        return resolve();
      }).catch(console.log);
  });
};

我希望它能在 1 秒内下载并关闭。关闭文件需要整整 10 秒,但我已经可以立即在我的电脑上看到它并阅读它。 1 个文件大约 700kb。

编辑: FTP 连接立即关闭,但 stream.pipe(fs.createWriteStream(${steamid}.json));需要 10 秒来调用 'close' 事件,尽管文件看起来立即完全下载。

编辑 2: There is a gap of 10 seconds after the 680 (thats the chunk.length) and then the Write stream is finished.

它好像不知道没有更多的数据来了。

编辑 3: 所以我下载的文件大约有 700 字节,每次最多只有 1 个块。我通过在读取流上添加一个 "data" 事件来修复它,在 1 个块之后我就销毁它。我的整个下载、编辑、上传工作现在不到一秒钟。 这可能不是一个理想的解决方案

根据 promise-ftp npm 文档,如果您想立即关闭 FTP 连接,您应该使用以下方法:

destroy(): Closes the connection to the server immediately. Returns a boolean indicating whether the connection was connected prior to the call to destroy().

你的情况是:

const getFile = () => {
  return new Promise((resolve, reject) => {
    console.log('getting file.');
    ftp.connect(config)
      .then(function (serverMessage) {
        return ftp.get(remoteFile + '.json');
      }).then(function (stream) {
        return new Promise(function (resolve, reject) {
          stream.once('close', resolve);
          stream.once('error', reject);
          stream.pipe(fs.createWriteStream(`${steamid}.json`));
        });
      }).then(async function () {
        console.log('done editing');
        await ftp.destroy();
        return resolve();
      }).catch(console.log);
  });
};

我知道这个 post 很旧,但我有同样的问题。 最后我采纳了 Marcel 的想法。刚刚通过查看下载文件的大小进行了改进。

var ftp = require('ftp');         // Client FTP
var fs  = require('fs');          // Gestion Fichier      

// Initialization
var distantFile     = 'example.dat';
var localFile           = distantFile;
var downloadedSize  = 0;
var fileSize        = 0;
        
var clientFtp = new ftp();
        
clientFtp.on('ready', function() {

    clientFtp.list(distantFile,function(errotList, listeElementDistant) {
            
            if(!errotList)
            {
                fileSize = listeElementDistant[0].size;

                clientFtp.get(distantFile, function(errotGet, stream) {

                    if(!errotGet)
                    {
                        stream.pipe(fs.createWriteStream(localFile));

                        stream.on('data',function(buffer){
                            downloadedSize += buffer.length;
                            console.log(downloadedSize+' '+fileSize+' '+(downloadedSize/fileSize*100).toFixed(1)+'%');


                            if(downloadedSize==fileSize)
                            {
                             clientFtp.end();
                             stream.destroy();
                             console.log('Download Complete');
                            }
                        });


                        stream.on('close', function(){
                            clientFtp.end();
                        });
                    }
                    else
                    {
                        console.log('Error Get : '+errotGet);
                    }

                });
            }
            else
            {
                console.log('Error List : '+errotList);
            }

        });
});

clientFtp.connect(/*  You Must Define Options Connections */);