如何使用 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 */);
我必须从 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 */);