首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ssh2-sftp-当侦听流数据事件时,客户端文件上传不完整

Ssh2-sftp-当侦听流数据事件时,客户端文件上传不完整
EN

Stack Overflow用户
提问于 2022-02-06 00:01:17
回答 1查看 525关注 0票数 0

我通过ssh2-sftp客户端通过传递一个readStream上传文件。这很好,但是当我添加事件侦听器时,文件并没有完全上传:

这样做是可行的:

代码语言:javascript
复制
const stream = fs.createReadStream(myFile);
return this.sftpClient.put(stream, remoteFilePath)

这只会上传80%的文件。

代码语言:javascript
复制
const stream = fs.createReadStream(myFile);
stream.on('data', (chunk) => {
  console.log('chunk passed');
});
return this.sftpClient.put(stream, remoteFilePath)

调试模式下的最后一条消息显示没有错误:

代码语言:javascript
复制
chunk passed
Outbound: Sending CHANNEL_DATA (r:0, 9380)
SFTP: Outbound: Sent WRITE (id:1554)
Inbound: CHANNEL_DATA (r:0, 28)
SFTP: Inbound: Received STATUS (id:1554, 0, "Success")
Outbound: Sending CHANNEL_DATA (r:0, 17)
SFTP: Outbound: Buffered CLOSE
Inbound: CHANNEL_DATA (r:0, 28)
SFTP: Inbound: Received STATUS (id:1555, 0, "Success")
CLIENT[sftp]: put: promise resolved
CLIENT[sftp]: put: Removing temp event listeners

同样的问题,当管道流:

代码语言:javascript
复制
const stream = fs.createReadStream(myFile);
const fileMd5Hash = crypto.createHash('md5').setEncoding('hex');
stream.pipe(fileMd5Hash);
return this.sftpClient.put(stream, remoteFilePath)

问题似乎在于,onData事件和管道()都将流转换为流模式,这可能会导致数据丢失,因为数据会立即“尽快”传递给应用程序。因此,我想知道:如果不将读取流切换到流模式,如何读取块来从整个文件中创建md5sum哈希呢?

EN

回答 1

Stack Overflow用户

发布于 2022-02-07 08:15:59

因此,我现在想出了发生什么:我跳过了我的例子中的一行,我认为这与此无关:

代码语言:javascript
复制
const stream = fs.createReadStream(myFile);

createDirsIfNotExist(remoteFilePath);

return this.sftpClient.put(stream, remoteFilePath)

所以我有:

代码语言:javascript
复制
const stream = fs.createReadStream(myFile);

stream.on('data', (chunk) => {
  console.log('chunk passed');
});

createDirsIfNotExist(remoteFilePath);

return this.sftpClient.put(stream, remoteFilePath)

问题是stream.on(数据.)立即触发切换到流模式。如果createDirsIfNotExist花费一些时间,那么第一个块将不会在sftpClient中使用管道。

如果我换了线路:

代码语言:javascript
复制
createDirsIfNotExist(remoteFilePath);

stream.on('data', (chunk) => {
  console.log('chunk passed');
});

return this.sftpClient.put(stream, remoteFilePath)

它如预期的那样工作。要成为shure,我在简历事件处理程序中包装了数据事件处理程序:

代码语言:javascript
复制
let listening = false;
stream.on('resume', () => {
  if(!listening) {
    stream.on('data', (chunk) => {
      console.log('chunk passed');
      // do whatever else is needed
    });
    listening = true;
});

这避免了时间问题,但看起来很奇怪。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71003169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档