Node.js 从可写到可读的管道数据

Node.js 从可写到可读的管道数据,node.js,typescript,stream,Node.js,Typescript,Stream,我正在从SFTP服务器获取文件,并使用sdk将数据传输到Box.com。Box sdk将可读流作为上传文件的参数。我为从sftp服务器获取文件而编写的代码使用npm模块ssh2-sftp-client 我遇到的问题是,可写流是流的“行尾”,除非您使用类似于双工的转换,并且实现读写。下面是我正在使用的代码。因为我是为一个客户做这件事的,所以我故意省略了一些不必要的东西 下面是sftp类的方法 async getFile(filepath: string): Promise<Readable&

我正在从SFTP服务器获取文件,并使用sdk将数据传输到Box.com。Box sdk将可读流作为上传文件的参数。我为从sftp服务器获取文件而编写的代码使用npm模块
ssh2-sftp-client

我遇到的问题是,可写流是流的“行尾”,除非您使用类似于双工的转换,并且实现读写。下面是我正在使用的代码。因为我是为一个客户做这件事的,所以我故意省略了一些不必要的东西

下面是sftp类的方法

async getFile(filepath: string): Promise<Readable> {
  logger.info(`Fetching file: ${filepath}`);
  const writable = new Writable();
  const stream = new PassThrough();
  await this.client.get(filepath, writable);
  return writable.pipe(stream);
}
我对溪流并不十分精通,但根据我的研究,我认为这在理论上应该是可行的

我还尝试了这个实现,其中ssh客户端返回一个缓冲区,然后尝试将该缓冲区作为可读流进行管道传输。但是,在这个实现中,我不断从Box sdk中得到错误,流意外结束

async getFile(filepath: string): Promise<Readable> {
  logger.info(`Fetching file: ${filepath}`);
  const stream = new Readable();
  const buffer = (await this.client.get(filepath)) as Buffer;
  stream._read = (): void => {
    stream.push(buffer);
    stream.push(null);
  };
  return stream;
}
异步getFile(filepath:string):承诺{ info(`Fetching file:${filepath}`); const stream=new Readable(); constbuffer=(等待this.client.get(filepath))作为缓冲区; 流。_read=():void=>{ 流推(缓冲); stream.push(空); }; 回流; } 并且错误消息:
2020-02-06 15:24:57错误:无法移动文件:错误:意外的API响应[400错误请求]错误请求-流意外结束


非常感谢您的任何见解

因此,在对此做了更多的研究之后,事实证明,问题实际上与Box sdk for Node有关。sdk在流主体实际完成之前终止流主体。这是因为在引擎盖下,他们正在使用
请求
库,该库需要
内容长度
头来发送大型有效负载。如果没有这一点,它将继续在发送有效负载之前终止流

在Box社区论坛上,他们建议向流原型添加属性,以便将内容传递到底层请求库。我强烈反对这一点,因为这不是正确的做法。Box sdk需要提供一种以字节为单位传递内容长度的方法。作为API的用户,我不必操纵它们的底层依赖关系。我将打开一个问题与他们的sdk,并希望得到修复

希望这对其他人有用

async getFile(filepath: string): Promise<Readable> {
  logger.info(`Fetching file: ${filepath}`);
  const stream = new Readable();
  const buffer = (await this.client.get(filepath)) as Buffer;
  stream._read = (): void => {
    stream.push(buffer);
    stream.push(null);
  };
  return stream;
}