这个问题是如何真正实现可读流的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()。
_writev()node.js中的正确用法是什么?该文件说:
如果流实现能够一次处理多个数据块,
writable._writev()则应实现该方法。
它还说:
其主要目的
writable.cork()是避免这样的情况:将许多小数据块写入流不会在内部缓冲区中造成备份,而这将对性能产生不利影响。在这种情况下,实现该writable._writev()方法的实现可以以更优化的方式执行缓冲的写入。
从流实现的角度来看,这是可以的。但从可写流消费者的角度来看,write或被writev调用的唯一方法是通过Writable.write()和writable.cork()
我想看一个小例子,它描述了实现的实际用例 _writev()
我有一个正在从音频源读取的流,我正在尝试将其存储到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文件系统调用。
如果我误解了文档或遗漏了一些明显的内容,请告诉我!
使用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) 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) 我在本地保存一个图像文件,以便我可以使用它准备好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) 请注意,有许多转换流可以执行此操作:
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)
不幸的是,我的转换流仍然不能接受对象,只能接受字符串/缓冲区。
import * as fs from 'node:fs';
const nodeReadable = fs.createReadStream('data.txt', {encoding: 'utf-8'});
Run Code Online (Sandbox Code Playgroud) 我到处寻找,所有的例子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) 我有一个 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-streams ×10
node.js ×10
buffer ×3
javascript ×2
form-data ×1
fs ×1
node-pdfkit ×1
nodemailer ×1
pdf ×1
sftp ×1