node.js: readSync à partir de stdin?
Est-il possible de lire de façon synchrone à partir de stdin dans node.js? Parce que je suis en train d'écrire un brainfuck à compilateur JavaScript en JavaScript (pour le plaisir). Brainfuck prend en charge une opération de lecture qui doit être mis en œuvre de manière synchrone.
J'ai essayé ceci:
const fs = require('fs');
var c = fs.readSync(0,1,null,'utf-8');
console.log('character: '+c+' ('+c.charCodeAt(0)+')');
Mais cela ne produit de cette sortie:
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
- Économisez du temps et de l'utilisation d'un bien entretenues mnp bibliothèque que les résumés de lecture à partir de stdin, npmjs.com/package/get-stdin.
Vous devez vous connecter pour publier un commentaire.
Je n'ai aucune idée de quand cela a montré jusqu'mais c'est une étape utile vers l'avant: http://nodejs.org/api/readline.html
Maintenant, je peux en lecture ligne-à-un-temps à partir de stdin. Les jours heureux.
readline
module est toujours classé comme2 - Unstable
deNode.js v0.10.4
.2 - Unstable
signifie que l'API n'est pas ferme et est sujette à changement. nodejs.org/api/documentation.html#documentation_stability_index. Je ne suis pas sûr de ce qu'il signifie à l'égard de la stabilité pour une utilisation.Stable
.rl.prompt
peutawait
ed; ou il peut être synchronisé.Avez-vous essayé:
Cependant, il faudra attendre pour la TOTALITÉ du fichier à lire, et ne reviendra pas sur \n comme scanf ou cin.
readFileSync()
appel des blocs jusqu'à ce que tous a été reçu (implicite par @dhruvbird de l'avertissement, mais il est utile d'indiquer explicitement).0
au lieu de/dev/stdin
fait la démarche de travail sur Windows aussi, mais comme de v9.11.1 il y a un bug quand il n'y a pas d'entrée ou stdin est fermé.Après jouer avec ce pour un peu, j'ai trouvé la réponse:
réponse sera un tableau à deux indices, le premier étant les données tapé dans la console et le second sera la longueur des données, y compris le caractère de saut de ligne.
Il était assez facile de déterminer quand vous
console.log(process.stdin)
qui énumère toutes les propriétés dont une intituléefd
qui est bien sûr le nom du premier paramètre pourfs.readSync()
Profitez-en!
😀
open()
appel sur stdin ne fonctionnera pas s'il est déjà ouvert. Pour contourner cela, je crois qu'ils ont besoin dedup()
la poignée si la poignée est 0 ou 1 etdup2()
la poignée de retour après l'achèvement. Mais là encore, je pourrais être terriblement incorrect :D. j'avais ouvert un ticket sur github et de laisser un peu de réel c devs vous donner la bonne réponse.node.js v0.10.4
, parce que les interfaces ont changé; voir ma réponse.Une version mise à jour de Marcus réponse du Pape qui fonctionne comme de node.js v0.10.4:
Veuillez noter:
2 - Unstable
denode.js v0.10.4
.OS X 10.8.3
etWindows 7
: la différence majeure est: de façon synchrone lecture interactive stdin d'entrée (en tapant dans le terminal, ligne par ligne) ne fonctionne que sur Windows 7.Voici le code mis à jour, lecture synchrone à partir de stdin en 256 octets morceaux jusqu'à ce que plus est disponible en entrée:
while(true)
?break
? Si bytesRead === 0 est votre état, pourquoi êtes-vous à l'aide de break?true
. Votre état est alors qu'il y a des octets dans stdin et si il n'y a pas d'erreur lors du traitement. C'est ce que je dis. C'est du code spaghetti.break
déclaration. Vous pouvez introduire une variable d'erreur qui est VRAI lorsqu'une erreur est trouvée lors de la lecture. Oui, ça vaut le coup, votre code est à vos documents.while(true)
ne veut rien dire pour moi.while(bytesRead != 0 && !error)
il n'.J'ai trouvé une bibliothèque qui doit être en mesure d'accomplir ce que vous avez besoin de: https://github.com/anseki/readline-sync
foo | bar
oùbar
utilise readline-sync va essayer de lire à partir du terminal, et non pas à partir de stdin.Important: je viens d'être informé par un Node.js contributeur qui
.fd
est sans-papiers et sert comme un moyen pour les internes des fins de débogage. Par conséquent, un code ne doit pas faire référence à ce, et devrait ouvrir manuellement le descripteur de fichier avecfs.open/openSync
.Dans Node.js 6, il est également intéressant de noter que la création d'une instance de
Buffer
via son constructeur avecnew
est déconseillée, en raison de sa nature non sécurisée. On devrait utiliserBuffer.alloc
à la place:Aussi, on ne doit que de l'ouvrir et de fermer le descripteur de fichier, le cas échéant; de faire cela chaque fois que l'on souhaite lire depuis l'entrée standard stdin résultats en surcharge inutile.
Ici est la mise en œuvre avec " asynchrone attendre`. Dans le code ci-dessous, l'entrée est prise à partir de l'entrée standard et après la réception de données de l'entrée standard est arrêté en attente de données à l'aide de processus.stdin.pause();`.
J'ai écrit un petit C++ module add-on, qui rendent la lecture synchrone sur le clavier (https://npmjs.org/package/kbd).
J'ai utilisé cette solution de contournement sur le nœud 0.10.24/linux:
Ce code attend en appuyant sur ENTRÉE. Il lit un caractère de la ligne, si l'utilisateur entre elle avant d'appuyer sur ENTRÉE. Les autres caractères seront restés dans le tampon de la console et sera lu lors des appels ultérieurs à readSync.
.next()
appel ou d'itération. Vérifier l'index.ts. Je pense que je devrais aussi fairedefaultChunkSize
comme un paramètre de l'utilisateur. Je vais pousser une mise à jour.J'ai écrit ce module de lire une ligne à la fois à partir d'un fichier ou l'entrée standard. Le module est nommé comme
line-reader
qui expose uneES6 *Generator function
pour effectuer une itération sur une ligne à la fois. voici un exemple de code(en caractères d'imprimerie) à partir de readme.md.En dehors de code ci-dessus, vous pouvez aussi jeter un oeil à
src > tests
dossier dans le repo.Remarque:-
ligne-lecteur de module ne pas lire tous les trucs en mémoire au lieu de cela il utilise la fonction de générateur pour générer des lignes asynchrones ou de synchronisation.