node.js:从标准输入读取同步?
是否可以从node.js中的stdin同步读取?因为我正在用 JavaScript 编写一个 Brainfuck 的 JavaScript 编译器(只是为了好玩)。 Brainfuck支持需要同步实现的读操作。
我尝试了这个:
const fs = require('fs');
var c = fs.readSync(0,1,null,'utf-8');
console.log('character: '+c+' ('+c.charCodeAt(0)+')');
但这只会产生这个输出:
fs:189
var r = binding.read(fd, buffer, offset, length, position);
^
Error: EAGAIN, Resource temporarily unavailable
at Object.readSync (fs:189:19)
at Object.<anonymous> (/home/.../stdin.js:3:12)
at Module._compile (module:426:23)
at Module._loadScriptSync (module:436:8)
at Module.loadSync (module:306:10)
at Object.runMain (module:490:22)
at node.js:254:10
Is it possible to synchronously read from stdin in node.js? Because I'm writing a brainfuck to JavaScript compiler in JavaScript (just for fun). Brainfuck supports a read operation which needs to be implemented synchronously.
I tried this:
const fs = require('fs');
var c = fs.readSync(0,1,null,'utf-8');
console.log('character: '+c+' ('+c.charCodeAt(0)+')');
But this only produces this output:
fs:189
var r = binding.read(fd, buffer, offset, length, position);
^
Error: EAGAIN, Resource temporarily unavailable
at Object.readSync (fs:189:19)
at Object.<anonymous> (/home/.../stdin.js:3:12)
at Module._compile (module:426:23)
at Module._loadScriptSync (module:436:8)
at Module.loadSync (module:306:10)
at Object.runMain (module:490:22)
at node.js:254:10
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您是否尝试过:
但是,它将等待读入整个文件,并且不会像 scanf 或 cin 那样在 \n 上返回。
Have you tried:
However, it will wait for the ENTIRE file to be read in, and won't return on \n like scanf or cin.
经过一番摆弄后,我找到了答案:
响应将是一个具有两个索引的数组,第一个是输入到控制台的数据,第二个是包括换行符在内的数据长度。
当您使用
console.log(process.stdin)
枚举所有属性时,很容易确定,其中包括一个标记为fd
的属性,它当然是第一个参数的名称对于fs.readSync()
尽情享受吧!
:D
After fiddling with this for a bit, I found the answer:
response will be an array with two indexes, the first being the data typed into the console and the second will be the length of the data including the newline character.
It was pretty easy to determine when you
console.log(process.stdin)
which enumerates all of the properties including one labeledfd
which is of course the name of the first parameter forfs.readSync()
Enjoy!
:D
Marcus Pope 答案的更新版本从 node.js v0.10.4 开始运行:
请注意:
2 - 不稳定
代码>node.js v0.10.4。OS X 10.8.3
和Windows 7
:主要区别是:同步读取交互式标准输入(通过在终端中逐行输入)仅适用于 Windows 7。以下是更新后的代码,以 256 字节块的形式从标准输入同步读取,直到没有更多输入可用:
An updated version of Marcus Pope's answer that works as of node.js v0.10.4:
Please note:
2 - Unstable
as ofnode.js v0.10.4
.OS X 10.8.3
andWindows 7
: the major difference is: synchronously reading interactive stdin input (by typing into the terminal line by line) only works on Windows 7.Here's the updated code, reading synchronously from stdin in 256-byte chunks until no more input is available:
我不知道这是什么时候出现的,但这是向前迈出的有用的一步: http://nodejs.org/api/readline.html
现在我可以从标准输入中一次读取一行。快乐的日子。
I've no idea when this showed up but this is a helpful step forward: http://nodejs.org/api/readline.html
Now I can read line-at-a-time from stdin. Happy days.
我找到了一个应该能够满足您需要的库: https://github.com/anseki/readline -同步
I found a library that should be able to accomplish what you need: https://github.com/anseki/readline-sync
重要提示: Node.js 贡献者刚刚通知我
.fd
未记录,用作内部调试目的的手段。因此,代码不应引用此文件,而应使用fs.open/openSync
手动打开文件描述符。在 Node.js 6 中,还值得注意的是,由于其不安全的性质,使用
new
通过其构造函数创建Buffer
实例已被弃用。人们应该使用 Buffer.alloc 来代替:此外,应该只在必要时打开和关闭文件描述符;每次希望从 stdin 读取数据时都执行此操作会导致不必要的开销。
Important: I've just been informed by a Node.js contributor that
.fd
is undocumented and serves as a means for internal debugging purposes. Therefore, one's code should not reference this, and should manually open the file descriptor withfs.open/openSync
.In Node.js 6, it's also worth noting that creating an instance of
Buffer
via its constructor withnew
is deprecated, due to its unsafe nature. One should useBuffer.alloc
instead:Also, one should only open and close the file descriptor when necessary; doing this every time one wishes to read from stdin results in unnecessary overhead.
以下代码从 stdin 读取同步。读取输入直到出现换行符/回车键。该函数返回输入的字符串,并丢弃换行符 (\n) 和回车符 (\r)。这应该与 Windows、Linux 和 Mac OSX 兼容。添加了对 Buffer.alloc 的条件调用(new Buffer(size) 目前已弃用,但某些旧版本缺少 Buffer.alloc。
The following code reads sync from stdin. Input is read up until a newline / enter key. The function returns a string of the input with line feeds (\n) and carriage returns (\r) discarded. This should be compatible with Windows, Linux, and Mac OSX. Added conditional call to Buffer.alloc (new Buffer(size) is currently deprecated, but some older versions lack Buffer.alloc.
这是“async wait”的实现。在下面的代码中,输入从标准输入获取,接收数据后,标准输入通过使用“process.stdin.pause();”停止等待数据。
Here is the implementation with `async await`. In the below code, the input is taken from standard input and after receiving data the standard input is stopped waiting for data by using `process.stdin.pause();`.
我在节点 0.10.24/linux 上使用了此解决方法:
此代码等待按 ENTER 键。如果用户在按 ENTER 键之前输入该字符,则它会从行中读取一个字符。其他字符将保留在控制台缓冲区中,并在后续调用 readSync 时读取。
I used this workaround on node 0.10.24/linux:
This code waits for pressing ENTER. It reads one character from line, if user enters it before pressing ENTER. Other characters will be remained in the console buffer and will be read on subsequent calls to readSync.
我编写了这个 模块 来一次从文件或标准输入中读取一行。该模块被命名为
line-reader
,它公开了一个ES6 *Generator 函数
来一次迭代一行。这是来自 readme.md 的代码示例(TypeScript 格式)。除了上面的代码,你还可以看一下
src > repo 中的tests
文件夹。注意:-
line-reader 模块不会将所有内容读取到内存中,而是使用生成器函数来生成行异步或同步。
I wrote this module to read one line at a time from file or stdin. The module is named as
line-reader
which exposes anES6 *Generator function
to iterate over one line at a time. here is a code sample(in TypeScript) from readme.md.Apart from above code, you can also take a look at
src > tests
folder in the repo.Note:-
line-reader module doesn't read all stuff into memory instead it uses generator function to generate lines async or sync.