标签: node-streams

_read()未在可读流上实现

这个问题是如何真正实现可读流的read方法。

我有一个Readable流的实现:

import {Readable} from "stream";
this.readableStream = new Readable();
Run Code Online (Sandbox Code Playgroud)

我收到此错误

events.js:136 throw er; //未处理的“错误”事件^

错误[ERR_STREAM_READ_NOT_IMPLEMENTED]:未在Readable._read(_stream_visible.js:445:10)处在readable.read(_stream_read.js:445:10)在_combinedTickCallback处的履历(_stream_read.js:445:10)上​​未实现_read() (内部/流程/next_tick.js:138:11)在启动时(bootstrap_node)在Function.Module.runMain(模块.js:684:11)的process._tickCallback(内部/流程/next_tick.js:180:9) js:191:16)在bootstrap_node.js:613:3

错误发生的原因很明显,我们需要这样做:

  this.readableStream = new Readable({
      read(size) {
        return true;
      }
    });
Run Code Online (Sandbox Code Playgroud)

我不太了解如何实现read方法。

唯一可行的就是打电话

this.readableStream.push('some string or buffer');
Run Code Online (Sandbox Code Playgroud)

如果我尝试做这样的事情:

   this.readableStream = new Readable({
          read(size) {
            this.push('foo');   // call push here!
            return true;
          }
     });
Run Code Online (Sandbox Code Playgroud)

然后什么也没发生-可读性就没有了!

此外,这些文章说您不需要实现read方法:

https://github.com/substack/stream-handbook#creating-a-visible-stream

https://medium.freecodecamp.org/node-js-streams-everything-you-need-to-know-c9141306be93

我的问题是 -为什么在read方法中调用push不起作用?对我唯一有用的就是在其他地方调用read.push()。

node.js node-streams nodejs-stream

6
推荐指数
2
解决办法
5586
查看次数

正确使用node.js中的_writev

_writev()node.js中的正确用法是什么?该文件说:

如果流实现能够一次处理多个数据块,writable._writev()则应实现该方法。

它还说:

其主要目的writable.cork()是避免这样的情况:将许多小数据块写入流不会在内部缓冲区中造成备份,而这将对性能产生不利影响。在这种情况下,实现该writable._writev()方法的实现可以以更优化的方式执行缓冲的写入。

从流实现的角度来看,这是可以的。但从可写流消费者的角度来看,write或被writev调用的唯一方法是通过Writable.write()writable.cork()

我想看一个小例子,它描述了实现的实际用例 _writev()

node.js node-streams

5
推荐指数
1
解决办法
1129
查看次数

将流写入缓冲区对象

我有一个正在从音频源读取的流,我正在尝试将其存储到Buffer. 从我读过的文档来看,您可以使用而不是文件路径将pipe流传输到一个流中。fs.createWriteStream(~buffer~)

我目前正在这样做:

const outputBuffer = Buffer.alloc(150000)
const stream = fs.createWriteStream(outputBuffer)
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,它会抛出一个错误,指出Path: must be a string without null bytes文件系统调用。

如果我误解了文档或遗漏了一些明显的内容,请告诉我!

buffer fs node.js node-streams

5
推荐指数
1
解决办法
1万
查看次数

下载多个 SFTP 文件时出现 NodeJS 错误“检测到可能的 EventEmitter 内存泄漏。添加了 11 个错误侦听器”

使用ssh2-sftp-client库从 SFTP 站点下载多个文件时出现错误。抛出的错误似乎表明每次下载完成后节点流都没有被清除。这导致我的应用程序出现内存泄漏。在生产中,我需要能够下载数千个文件,因此这种内存泄漏非常严重。如何关闭流以便在每个文件下载后释放内存?

代码:

const Client = require('ssh2-sftp-client');

const sftp = new Client();
sftp.connect({
  host: '195.144.107.198',
  port: 22,
  username: 'demo',
  password: 'password'
}).then(async () => {

  const fileNames = ['readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt'];

  // Loop through filenames
  for (let i = 0; i < fileNames.length; i++) {

    // Download all the files synchronously (1 at a time)
    const fileName = fileNames[i];
    await new Promise((resolve, reject) => { // <-- note …
Run Code Online (Sandbox Code Playgroud)

javascript sftp node.js node-streams

5
推荐指数
1
解决办法
984
查看次数

Node PDFKit pipe to multiple targets

I'm having a problem, when I have to pipe() the created document to multiple targets, in my case to a HTTP response and to an email attachment using node-mailer. After the first use in an attachment to an email, nothing gets piped to a response (when calling it from the client, the PDF has 0 bytes).

Response controller:

const doc = await createPdf(course.name, lastRecordDate, ctx);   

// Send a notificiation email with attachment
if (query.hasOwnProperty('sendEmail') && query.sendEmail === 'true') { …
Run Code Online (Sandbox Code Playgroud)

pdf node.js nodemailer node-pdfkit node-streams

5
推荐指数
1
解决办法
53
查看次数

nodeJS 将 Buffer 转换为 fs.ReadStream 对象

我在本地保存一个图像文件,以便我可以使用它准备好fs.createReadStream()并将其附加到我的FormData以将其发送到 REST api。像这样:(我正在使用 trello api https://developer.atlassian.com/cloud/trello/rest/#api-cards-id-attachments-post

const fetch = require('node-fetch');
const Jimp = require('jimp');
const FormData = require('form-data');

// Save file locally
await Jimp.read(imagePNGURL).writeAsync(savedImagePath);

// Append it to the formdata using fs.createReadStream
const formData = new FormData();
formData.append('file', fs.createReadStream(savedImagePath));

// Send formData to api and image gets saved correctly
await fetch('TrelloUrl', { method: 'POST', body: formData })
Run Code Online (Sandbox Code Playgroud)

现在我想做同样的事情,但保存本地文件,而是使用图像缓冲区。我尝试了以下方法,但似乎无法使其工作:

const fetch = require('node-fetch');
const Jimp = require('jimp');
const FormData = require('form-data');
const …
Run Code Online (Sandbox Code Playgroud)

javascript buffer form-data node.js node-streams

5
推荐指数
1
解决办法
3022
查看次数

使用转换流将 JS 对象转换为 JSON

请注意,有许多转换流可以执行此操作:

JSON -> JS

但我希望创建一个可以执行以下操作的 Node.js 转换流:

JS -> JSON

我有一个可读的流:

const readable = getReadableStream({objectMode:true});
Run Code Online (Sandbox Code Playgroud)

可读流输出对象,而不是字符串。

我需要创建一个转换流,它可以过滤其中一些对象并将这些对象转换为 JSON,如下所示:

const t = new Transform({
  objectMode: true,
  transform(chunk, encoding, cb) {
    if(chunk && chunk.marker === true){
       this.push(JSON.stringify(chunk));
     }
    cb();
  },
  flush(cb) {
    cb();
  }
});
Run Code Online (Sandbox Code Playgroud)

但是,由于某种原因,我的转换流无法接受转换方法的对象,只能接受字符串和缓冲区,我该怎么办?

我尝试添加这两个选项:

  const t = new Transform({
      objectMode: true,
      readableObjectMode: true,  // added this
      writableObjectMode: true,  // added this too
      transform(chunk, encoding, cb) {
        this.push(chunk);
        cb();
      },
      flush(cb) {
        cb();
      }
    });
Run Code Online (Sandbox Code Playgroud)

不幸的是,我的转换流仍然不能接受对象,只能接受字符串/缓冲区。

node.js node-streams nodejs-stream

4
推荐指数
1
解决办法
3661
查看次数

将节点流转换为Web流

如何将NodeJS 流转换为Web 流

import * as fs from 'node:fs';
const nodeReadable = fs.createReadStream('data.txt', {encoding: 'utf-8'});
Run Code Online (Sandbox Code Playgroud)

node.js node-streams

4
推荐指数
1
解决办法
1286
查看次数

如何通过管道传输到作为缓冲区而不是文件的 Node.js 流?

我到处寻找,所有的例子fs.createWriteStream都不是我想要的。

我正在使用该archiver包,并且想使用archive.pipe()管道传输到一个可写流,该流不是文件,而是一个缓冲区,我可以使用它发送s3.putObject到 S3 存储桶。如何设置可以通过管道传输到的缓冲区?

当我运行下面的代码时,我收到“错误:未实现”。

const stream = require('stream');
const archiver = require('archiver');

const archive = archiver('zip');
const outputStream = new stream.Writable();
outputStream.on('close', () => {
  console.log('done');
});
outputStream.on('error', err => {
  console.error(err);
});
archive.pipe(outputStream);
archive.append('Testing 1 2 3', { name: 'file1.txt' });
archive.finalize();
Run Code Online (Sandbox Code Playgroud)

buffer node.js node-streams

3
推荐指数
1
解决办法
2851
查看次数

write() (不带回调)是否保留 Node.js 写入流中的顺序?

我有一个 node.js 程序,在其中使用流将信息写入 SFTP 服务器。像这样(简化版):

var conn = new SSHClient();
process.nextTick(function (){      
   conn.on('ready', function () {
      conn.sftp(function (error, sftp) {
         var writeStream = sftp.createWriteStream(filename);
         ...
         writeStream.write(line1);
         writeStream.write(line2);
         writeStream.write(line3);
         ...
      });
    }).connect(...);
});
Run Code Online (Sandbox Code Playgroud)

注意我没有使用(可选)回调参数(在write() API 规范中描述),并且我不确定这是否会导致不良行为(即未按以下顺序写入的行:line1、line2、line3) 。换句话说,我不知道是否应该使用这种替代方案(更复杂的代码并且不确定是否效率较低):

writeStream.write(line1, ..., function() {
   writeStream.write(line2, ..., function() {
      writeStream.write(line3);
   });
});
Run Code Online (Sandbox Code Playgroud)

(或使用async series() 的等效替代方案)

根据我的测试经验,我总是按照所需的顺序写入文件(我的意思是,首先是第 1 行,然后是第 2 行,最后是第 3 行)。但是,我现在不知道这是否只是偶然发生,或者上面是使用 write() 的正确方法。

我知道流中的写入通常是异步的(所有 I/O 工作都应该是异步的),但我想知道 Node.js 中的流是否保留内部缓冲区或类似的东西来保持数据有序,因此每个 write() 调用都不会返回直到数据被放入该缓冲区。

在实际程序中使用 write() 的示例非常受欢迎。谢谢!

node.js node-streams

3
推荐指数
1
解决办法
960
查看次数