我正在使用Node.js编写一个程序,在某些情况下,它需要作为简单的过滤器:读取stdin中的所有内容(直到文件末尾),进行一些处理,然后将结果写入stdout。
如何实现“读取stdin中的所有内容”部分?目前我找到的最接近的解决方案似乎只适用于从控制台逐行读取或仅在stdin是文件而不是管道时才起作用。
如何实现“读取stdin中的所有内容”部分?目前我找到的最接近的解决方案似乎只适用于从控制台逐行读取或仅在stdin是文件而不是管道时才起作用。
var fs = require('fs');
var data = fs.readFileSync(0, 'utf-8');
// data is a string containing the file's contents
我在使用Node 11+中的以下内容
async function read(stream) {
const chunks = [];
for await (const chunk of stream) chunks.push(chunk);
return Buffer.concat(chunks).toString('utf8');
}
用法:
const input = await read(process.stdin);
如果您使用的是 Linux 系统,则无需使用第三方软件包进行此操作。当然,需要考虑您的性能需求,但以下两行代码可以解决问题:
const fs = require("fs");
const data = fs.readFileSync("/dev/stdin", "utf-8");
在下面的评论中,Jan指出更具可移植性的解决方案是使用0
,因为这是POSIX标准。因此,您可以简单地使用:
Jan在下面的评论中指出,使用0
是更具可移植性的解决方案,因为它符合POSIX标准。因此,您只需简单地使用:
const fs = require("fs");
const data = fs.readFileSync(0, "utf-8");
data
现在是一个从标准输入读取的数据字符串,解释为 utf-8 编码。
fs.readFileSync(0, 'utf8')
,这在任何地方都可以工作。(文件描述符0是标准输入)。 - Jan Schär'/dev/stdin'
和 0
在 macOS 上都可以使用。 - knpwrsget-stdin可以解决问题。
在你的问题中阅读到一些隐含信息。
由于你标记了问题为“同步”,我需要指出stdin在node.js中仅支持异步。上面提到的库是最简单的方法。它将整个输入处理为字符串或缓冲区。
如果可能,以流式编程方式编写程序是最好的,但某些用例对于流式编程是可行的(例如单词计数),而某些用例则不然(例如反转输入)。
另外,“从控制台逐行读取”是终端缓冲区存储您的按键所导致的现象。如果想要更多细节,请查看神奇的TTY Demystified。
我在这里没有看到实际上同步的解决方案,除了@Patrick Narkinsky的。但是@Patrick Narkinsky的答案在Windows上不起作用。似乎是一个node.js的bug。如果你想了解详情,请随意深入研究这些github问题,但是我在阅读了一个小时后放弃了。
我在那里没有找到解决方法(可能是我忽略了),但我意外地发现了一个解决问题的方法。它不太美观,但它有效。由于该链接只显示如何记录进度,因此我必须根据自己的需求进行修改:
import fs from 'fs';
const BUFSIZE = 256;
const buf = Buffer.alloc(BUFSIZE);
let bytesRead;
let stdin = '';
export function stdinToString(): string {
do {
// Loop as long as stdin input is available.
bytesRead = 0;
try {
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
} catch (e) {
if (e.code === 'EAGAIN') {
// 'resource temporarily unavailable'
// Happens on OS X 10.8.3 (not Windows 7!), if there's no
// stdin input - typically when invoking a script without any
// input (for interactive stdin input).
// If you were to just continue, you'd create a tight loop.
throw 'ERROR: interactive stdin input not supported.';
} else if (e.code === 'EOF') {
// Happens on Windows 7, but not OS X 10.8.3:
// simply signals the end of *piped* stdin input.
break;
}
throw e; // unexpected exception
}
if (bytesRead === 0) {
// No more stdin input available.
// OS X 10.8.3: regardless of input method, this is how the end
// of input is signaled.
// Windows 7: this is how the end of input is signaled for
// *interactive* stdin input.
break;
}
// Process the chunk read.
stdin += buf.toString(undefined, 0, bytesRead);
} while (bytesRead > 0);
return stdin;
}
fs.readFileSync(process.stdin.fd, 'utf-8')
可能更易读,这样读者就清楚地知道它是标准输入。 - Nicholas Daley-OkoyeError: EAGAIN:resource temporarily unavailable, read
。但是这个答案中的方法仍然可以正常工作。 - Sam