读线在55行之后停止。如何从Node JS中的标准输入读取输入?

时间:2019-03-15 11:37:41

标签: javascript node.js readline

我有一个“简单”的问题,似乎无法解决。我只是要从标准输入(终端)读取输入,然后将输入保存到变量(这里是数组),然后将其全部打印到终端。当我尝试粘贴超过55行的文本时,该程序仅打印出(我输入的)前55行,然后退出。我不明白为什么会停止以及如何解决此问题。

我的代码是:

let readline = require('readline');
let rl = readline.createInterface({
    input: process.stdin,
    terminal: true
})

let inputLines = []

const pushLinesToArray = function (line) {
    inputLines.push(line)
  }

const readOneLine = function () {
    return new Promise((resolve, reject) => {
        rl.on('line', resolve)  
        }).then(rl.on('line', pushLinesToArray))
}

const start = async () => {

    // Save all input to inputLines array
    await readOneLine()

    // Print inputLines array to terminal/console
    inputLines.forEach((line) => console.log(line))
    process.exit()
}

start()

如何解决这个问题? 我还应该提到,如果我使用ctrl + C(Mac OSX)关闭程序,则将上面的函数(readOneLine)更改为下面的代码时,它将起作用。这让我觉得它没有与maxLineLength或内存缓冲区做任何事情。我在下面唯一更改的是close,而不是第一个line

rl.on
const readOneLine = function () {
    return new Promise((resolve, reject) => {
        rl.on('close', resolve)  
        }).then(rl.on('line', pushLinesToArray))
}

我还应该提到,在实际打印输出之前,我将对其进行一些处理。在上面的代码中,我将所有内容都删除了,因为我意识到读取输入已经存在问题。 即我想读取超过55行文本的输入。然后将文本保存到数组(逐行)。然后执行我的其他代码(计算每个人的负债额)。最后将其打印出来。

示例输入将如下所示: Note that there is new line after line 12

当我复制->时,将其粘贴为输入(并标记每行(1-13))此工作。另一方面,如果我有这样的57行(其中nr 1-56行包含文本,nr 57行为空),则该行不起作用。然后我的程序在打印前55行文本后退出(第56行永远不会打印)

编辑:我需要使用它来处理Kattis(在线编程问题网站),我唯一知道的是他们正在使用上述标志运行我的代码:-c {files}。我需要修改代码,以便它可以处理3行到100000行之间的所有内容的不同输入。输入将始终成块出现(将所有行copy->粘贴到终端中的字符串),在打印输出答案之前,我需要附加监听器或读取此输入并对其进行处理(计算所有内容)终点站。因此,我仍在寻找解决此输入问题的答案。

2 个答案:

答案 0 :(得分:1)

我认为您面临的问题是因为 readline 带有默认的4K缓冲区大小,超过该大小将无法读取。您必须在其选项中设置 maxLineLength

引用this

答案 1 :(得分:1)

在这种情况下,promise的用法需要更改。因为在读取的第一行中的承诺 resolves ,所以await中的start()会解除阻塞,并准备处理到那时已读取了多少行。输入被削减的原因可能是您没有足够的时间来读取所有输入。

要么删除promise,然后处理行:

rl.on('line', (line) => console.log(line));

或者然后使用close事件来解决承诺并在读取所有内容后处理所有输入。

const readOneLine = function () {
    return new Promise((resolve, reject) => {
        rl.on('line', pushLinesToArray)
        rl.on('close', () => resolve(inputLines))  
    })
}

readline标准模块[1]的node.js文档中所述,close事件在客户端读取或关闭所有可用输入后执行。

由于您还希望将空行作为流的结束标记,因此可以在line event中完成。

const readOneLine = function () {
    return new Promise((resolve, reject) => {
        rl.on('line', (line) => {
            if (line === '') {
                resolve(inputLines);
                rl.close();
                return;
            }
            pushLinesToArray(line)
        })
        rl.on('close', () => resolve(inputLines))  
    })
}

第一个有机会运行的resolve()会解除await的阻塞。如果resolve()在空行和Ctrl + C之后运行两次,则不会造成任何危害。

[1] https://nodejs.org/api/readline.html#readline_event_close