pan*_*nzi 51 stdin synchronous node.js
是否可以从node.js中的stdin同步读取?因为我正在用JavaScript编写一个关于JavaScript编译器的脑筋(只是为了好玩).Brainfuck支持需要同步实现的读取操作.
我试过这个:
const fs = require('fs');
var c = fs.readSync(0,1,null,'utf-8');
console.log('character: '+c+' ('+c.charCodeAt(0)+')');
Run Code Online (Sandbox Code Playgroud)
但这只产生这个输出:
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
Run Code Online (Sandbox Code Playgroud)
dhr*_*ird 54
你有没有尝试过:
fs=require('fs');
console.log(fs.readFileSync('/dev/stdin').toString());
Run Code Online (Sandbox Code Playgroud)
但是,它会等待读入整个ENTIRE文件,并且不会像scanf或cin那样返回.
Mar*_*ope 27
在摆弄了一下之后,我找到了答案:
process.stdin.resume();
var fs = require('fs');
var response = fs.readSync(process.stdin.fd, 100, 0, "utf8");
process.stdin.pause();
Run Code Online (Sandbox Code Playgroud)
response将是一个包含两个索引的数组,第一个是输入控制台的数据,第二个是包含换行符的数据长度.
很容易确定何时console.log(process.stdin)
枚举所有属性,包括一个标记的属性fd
,当然是第一个参数的名称fs.readSync()
请享用!:d
mkl*_*nt0 21
Marcus Pope的答案的更新版本,自node.js v0.10.4开始起作用:
请注意:
2 - Unstable
作为的node.js v0.10.4
.OS X 10.8.3
并且Windows 7
:主要区别在于:同步读取交互式标准输入(通过逐行输入终端)仅适用于Windows 7.这是更新的代码,以256字节的块从stdin同步读取,直到没有更多的输入可用:
var fs = require('fs');
var BUFSIZE=256;
var buf = new Buffer(BUFSIZE);
var bytesRead;
while (true) { // Loop as long as stdin input is available.
bytesRead = 0;
try {
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE);
} 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.
console.log('Bytes read: %s; content:\n%s', bytesRead, buf.toString(null, 0, bytesRead));
}
Run Code Online (Sandbox Code Playgroud)
rjp*_*rjp 19
我不知道什么时候出现,但这是一个有益的一步:http://nodejs.org/api/readline.html
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', function (cmd) {
console.log('You just typed: '+cmd);
});
Run Code Online (Sandbox Code Playgroud)
现在我可以从标准输入读取一次.快乐的时光.
Nat*_*ero 14
我找到了一个能够完成你需要的库:https://github.com/anseki/readline-sync
这是使用“async await”的实现。在下面的代码中,输入是从标准输入中获取的,在接收到数据后,标准输入通过使用 `process.stdin.pause();` 停止等待数据。
process.stdin.setEncoding('utf8');
// This function reads only one line on console synchronously. After pressing `enter` key the console will stop listening for data.
function readlineSync() {
return new Promise((resolve, reject) => {
process.stdin.resume();
process.stdin.on('data', function (data) {
process.stdin.pause(); // stops after one line reads
resolve(data);
});
});
}
// entry point
async function main() {
let inputLine1 = await readlineSync();
console.log('inputLine1 = ', inputLine1);
let inputLine2 = await readlineSync();
console.log('inputLine2 = ', inputLine2);
console.log('bye');
}
main();
Run Code Online (Sandbox Code Playgroud)
以下代码从 stdin 读取同步。读取输入直到出现换行符/回车键。该函数返回输入的字符串,并丢弃换行符 (\n) 和回车符 (\r)。这应该与 Windows、Linux 和 Mac OSX 兼容。添加了对 Buffer.alloc 的条件调用(new Buffer(size) 目前已弃用,但某些旧版本缺少 Buffer.alloc。
function prompt(){
var fs = require("fs");
var rtnval = "";
var buffer = Buffer.alloc ? Buffer.alloc(1) : new Buffer(1);
for(;;){
fs.readSync(0, buffer, 0, 1); //0 is fd for stdin
if(buffer[0] === 10){ //LF \n return on line feed
break;
}else if(buffer[0] !== 13){ //CR \r skip carriage return
rtnval += new String(buffer);
}
}
return rtnval;
}
Run Code Online (Sandbox Code Playgroud)
重要提示:我刚收到一个.fd
未记录的Node.js参与者的通知,并作为内部调试的一种手段.因此,一个人的代码不应该引用它,并且应该手动打开文件描述符fs.open/openSync
.
在Node.js 6中,值得注意的是,由于其不安全的特性,不建议Buffer
通过其构造函数创建实例new
.应该使用Buffer.alloc
:
'use strict';
const fs = require('fs');
// small because I'm only reading a few bytes
const BUFFER_LENGTH = 8;
const stdin = fs.openSync('/dev/stdin', 'rs');
const buffer = Buffer.alloc(BUFFER_LENGTH);
fs.readSync(stdin, buffer, 0, BUFFER_LENGTH);
console.log(buffer.toString());
fs.closeSync(stdin);
Run Code Online (Sandbox Code Playgroud)
此外,只应在必要时打开和关闭文件描述符; 每次想要从stdin读取时都这样做会导致不必要的开销.
function read_stdinSync() {
var b = new Buffer(1024)
var data = ''
while (true) {
var n = fs.readSync(process.stdin.fd, b, 0, b.length)
if (!n) break
data += b.toString(null, 0, n)
}
return data
}
Run Code Online (Sandbox Code Playgroud)