监听 (own) process.stdout (in Node.js)

Listen to (own) process.stdout (in Node.js)

提问人:Remirror 提问时间:12/9/2021 更新时间:1/20/2023 访问量:961

问:

对于那些熟悉这个话题的人来说,这可能是一个基本问题。考虑以下玩具程序:

  const fs = require('fs');
  process.stdout.on('data', (chunk) => {
    fs.writeFileSync('myfile.txt', chunk, 'utf-8'); // just an example
  });
  process.stdout.write('xyz');

如果我按原样运行此代码,则会出现以下错误:

  errno: -4053,
  code: 'ENOTCONN',
  syscall: 'read'

我已经不明白为什么会这样。但它变得更奇怪了:

当我在它前面带有 console.log() 运行代码时,不再抛出错误!但是,在这种情况下,我为事件定义的侦听器似乎没有执行,因为没有创建文本文件。data

有人可以向我解释为什么会发生这种情况以及我能做些什么来获得预期的结果(在这里写信给myfile.txt)?

node.js IO STDOUT

评论


答:

2赞 Colin Parsons 1/19/2023 #1

您看到的第一个错误是由尝试连接到以获取其 .你没有写任何东西,所以它没有初始化,所以你不能连接到它! 确切地说就是:(到套接字)。stdoutdatastdoutENOTCONNError: Not Connectedstdout

现在,对于第二个错误。 是 的别名。因此,当您在它之前运行代码时,您现在已经初始化了,因此您可以连接到它并且不会抛出错误。但是您正在等待来自控制台的输入。输入不是来自 stdout,而是来自 stdinconsole.log()process.stdout.write('\n')console.log()stdoutENOTCONNstdout

要解决此问题,您需要:

  1. 在连接到它之前进行初始化,使用 .stdinprocess.stdin.resume()
  2. 等待 from 而不是 ,使用 。datastdinstdoutprocess.stdin.on(...)
  3. 使用完成接收 的输入后成功退出程序。stdinprocess.exit(0)
const fs = require('fs')

process.stdin.resume()
process.stdin.on('data', (chunk) => {
  fs.writeFileSync('mytestfile.txt', chunk, 'utf-8')

  // Uncomment the following line if you want to write
  // something to the console to indicate success
  // process.stdout.write("Got your input!")

  process.exit(0)
})

评论

0赞 shiyon sufa 4/10/2023
那么,有没有办法捕捉在控制台上打印的所有内容的结果并将它们写入文件中?想象一下,我们编写 console.log('foo'),我们的代码捕获 foo 并将其写入我们的文件中。
1赞 Colin Parsons 4/11/2023
如果你问的是只从这个 Node 程序捕获控制台输出,stackoverflow.com/questions/47658413/... 给出了几个很好的答案!
0赞 Nikhil Butani 1/19/2023 #2

您看到的错误正在发生,因为流未发出数据事件。这意味着您定义的侦听器不会被调用,因此不会执行调用。process.stdoutwriteFileSync

至于为什么添加 a 可以解决问题,很可能是调用导致事件循环运行,进而导致发出数据事件。console.log()console.log

为了获得写入myfile.txt的预期结果,您应该尝试使用“end”事件而不是“data”事件。当没有更多数据要从流中读取时,将发出此事件。

试试这个:

process.stdout.on('end', () => {
    fs.writeFileSync('myfile.txt', 'xyz', 'utf-8');
});
process.stdout.end();

这会在发出“end”事件时将字符串“xyz”写入myfile.txt。 另一种选择是在 stdout.write() 之前直接写入文件。

fs.writeFileSync('myfile.txt', 'xyz', 'utf-8');
process.stdout.write('xyz');

无论哪种方式,它都将确保在进程退出之前写入您的文件。