Created
September 12, 2014 11:32
-
-
Save espadrine/172658142820a356e1e0 to your computer and use it in GitHub Desktop.
How to read stdin synchronously in nodejs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'); | |
// Returns a buffer of the exact size of the input. | |
// When endByte is read, stop reading from stdin. | |
function getStdin(endByte) { | |
var BUFSIZE = 256; | |
var buf = new Buffer(BUFSIZE); | |
var totalBuf = new Buffer(BUFSIZE); | |
var totalBytesRead = 0; | |
var bytesRead = 0; | |
var endByteRead = false; | |
var fd = process.stdin.fd; | |
// Linux and Mac cannot use process.stdin.fd (which isn't set up as sync). | |
var usingDevice = false; | |
try { | |
fd = fs.openSync('/dev/stdin', 'rs'); | |
usingDevice = true; | |
} catch (e) {} | |
for (;;) { | |
try { | |
bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, null); | |
// Copy the new bytes to totalBuf. | |
var tmpBuf = new Buffer(totalBytesRead + bytesRead); | |
totalBuf.copy(tmpBuf, 0, 0, totalBytesRead); | |
buf.copy(tmpBuf, totalBytesRead, 0, bytesRead); | |
totalBuf = tmpBuf; | |
totalBytesRead += bytesRead; | |
// Has the endByte been read? | |
for (var i = 0; i < bytesRead; i++) { | |
if (buf[i] === endByte) { | |
endByteRead = true; | |
break; | |
} | |
} | |
if (endByteRead) { break; } | |
} catch (e) { | |
if (e.code === 'EOF') { break; } | |
throw e; | |
} | |
if (bytesRead === 0) { break; } | |
} | |
if (usingDevice) { fs.closeSync(fd); } | |
return totalBuf; | |
} | |
var stdin = ''; | |
function getline() { | |
if (stdin.length === 0) { | |
stdin = getStdin('\n'.charCodeAt(0)).toString('utf-8'); | |
} | |
var newline = stdin.search('\n') + 1; | |
var line = stdin.slice(0, newline); | |
// Flush | |
stdin = stdin.slice(newline); | |
return line; | |
} | |
console.log('First line: "' + getline() + '"'); | |
console.log('Second line: "' + getline() + '"'); |
If you use "readFileSync" in Linux, it would be fine. However, reading process.stdin.fd
first make it impossible to do that. Strange.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Does this work cross-platform? (i.e. Windows, Darwin and Linux)