node.js: readSync from stdin?

2019-01-13 17:39发布

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

11条回答
forever°为你锁心
2楼-- · 2019-01-13 17:44

An updated version of Marcus Pope's answer that works as of node.js v0.10.4:

Please note:

  • In general, node's stream interfaces are still in flux (pun half-intended) and are still classified as 2 - Unstable as of node.js v0.10.4.
  • Different platforms behave slightly differently; I've looked at OS X 10.8.3 and Windows 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:

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));
}
查看更多
▲ chillily
3楼-- · 2019-01-13 17:46

Have you tried:

fs=require('fs');
console.log(fs.readFileSync('/dev/stdin').toString());

However, it will wait for the ENTIRE file to be read in, and won't return on \n like scanf or cin.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-01-13 17:46
process.stdin.setEncoding('utf8');
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);
        });
    });
}

async function main() {
    let inputLine1 = await readlineSync();
    console.log('inputLine1 = ', inputLine1);
    let inputLine2 = await readlineSync();
    console.log('inputLine2 = ', inputLine2);
    console.log('bye');
}

main();
查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-13 17:48

I found a library that should be able to accomplish what you need: https://github.com/anseki/readline-sync

查看更多
Melony?
6楼-- · 2019-01-13 17:51
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
}
查看更多
劳资没心,怎么记你
7楼-- · 2019-01-13 17:54

I wrote a little C++ add-on module that make synchronous reading on keyboard (https://npmjs.org/package/kbd).

查看更多
登录 后发表回答