node.js:将文本文件读入数组。(每一行都是数组中的一个项目。)

IT技术 javascript node.js
2021-02-10 16:56:30

我想将一个非常非常大的文件读入 node.js 中的 JavaScript 数组。

所以,如果文件是这样的:

first line
two 
three
...
...

我会有数组:

['first line','two','three', ... , ... ] 

该函数将如下所示:

var array = load(filename); 

因此,将其全部加载为字符串然后将其拆分的想法是不可接受的。

6个回答

同步:

var fs = require('fs');
var array = fs.readFileSync('file.txt').toString().split("\n");
for(i in array) {
    console.log(array[i]);
}

异步:

var fs = require('fs');
fs.readFile('file.txt', function(err, data) {
    if(err) throw err;
    var array = data.toString().split("\n");
    for(i in array) {
        console.log(array[i]);
    }
});
我发现在 Windows 制作的文件上执行此操作,我不得不拆分 \r\n 但这破坏了 Mac;所以更健壮;_array = string.replace(/\r\n/g,'\n').split('\n'); 为两者工作
2021-03-13 16:56:30
+1 Stackoverflow 中存在一些问题。现在,我经常在向下滚动太多后找到高投票的答案。这也是一个例子。它具有最高的投票权,但位于页面底部,最末。我认为 Stackoverflow 需要改进他们的排序算法。
2021-03-16 16:56:30
@shashwat 提出问题的人可以决定哪个是正确答案。在这种情况下,他们需要一个大文件的流媒体解决方案,将整个文件放在一个字符串中是不可接受的。SO 没有错,真的。
2021-03-19 16:56:30
谢谢。不幸的是,我不得不编辑我的问题。我的意思是如何读取一个巨大的文件。在字符串中读取所有内容是不可接受的。
2021-04-03 16:56:30
@WillHancock 为什么不用那种怪异的东西呢os.EOL
2021-04-04 16:56:30

如果您可以将最终数据放入一个数组中,那么您是否也可以将它放入一个字符串中并将其拆分,就像建议的那样?在任何情况下,如果您想一次处理一行文件,您也可以尝试以下操作:

var fs = require('fs');

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    while (index > -1) {
      var line = remaining.substring(0, index);
      remaining = remaining.substring(index + 1);
      func(line);
      index = remaining.indexOf('\n');
    }
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

function func(data) {
  console.log('Line: ' + data);
}

var input = fs.createReadStream('lines.txt');
readLines(input, func);

编辑:(响应phopkins 的评论)我认为(至少在较新版本中) substring 不会复制数据,而是创建一个特殊的 SlicedString 对象(快速浏览 v8 源代码)。在任何情况下,这里都有一个避免提到的子字符串的修改(在一个value几兆字节的文件上进行测试,“所有工作和不玩耍使杰克成为一个无趣的男孩”):

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    var last  = 0;
    while (index > -1) {
      var line = remaining.substring(last, index);
      last = index + 1;
      func(line);
      index = remaining.indexOf('\n', last);
    }

    remaining = remaining.substring(last);
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}
我在大约 2MB 左右的文件上尝试了这个,它非常慢,比同步读取文件到字符串慢得多。我认为问题是剩余的 = 剩余的.substring 行。Node 的“数据”可能一次给你很多,并且对每一行进行复制很快就会变成 O(n^2)。
2021-04-08 16:56:30
@Finbar 的回答要好得多
2021-04-08 16:56:30
谢谢。回答你的问题:不,字符串会太大。
2021-04-12 16:56:30

使用 Node.js readline module

var fs = require('fs');
var readline = require('readline');

var filename = process.argv[2];
readline.createInterface({
    input: fs.createReadStream(filename),
    terminal: false
}).on('line', function(line) {
   console.log('Line: ' + line);
});
遗憾的是,此解决方案存在一个问题:如果文件末尾没有 ,则您不会得到最后一行\n参见:stackoverflow.com/questions/18450197/...
2021-03-28 16:56:30
节点已通过 \n stackoverflow.com/a/32599033/3763850解决了该问题
2021-03-30 16:56:30

js:

var array = fs.readFileSync('file.txt', 'utf8').split('\n');

ts:

var array = fs.readFileSync('file.txt', 'utf8').toString().split('\n');
为了防止上面的 throw TypeError: fs.readFileSync(...).split is not a function,你应该像这样使用 .toString() :var array = fs.readFileSync('file.txt', 'utf8').toString().split('\n');
2021-03-30 16:56:30

使用 readline(文档)。这是一个读取 css 文件、解析图标并将它们写入 json 的示例

var results = [];
  var rl = require('readline').createInterface({
    input: require('fs').createReadStream('./assets/stylesheets/_icons.scss')
  });


  // for every new line, if it matches the regex, add it to an array
  // this is ugly regex :)
  rl.on('line', function (line) {
    var re = /\.icon-icon.*:/;
    var match;
    if ((match = re.exec(line)) !== null) {
      results.push(match[0].replace(".",'').replace(":",''));
    }
  });


  // readline emits a close event when the file is read.
  rl.on('close', function(){
    var outputFilename = './icons.json';
    fs.writeFile(outputFilename, JSON.stringify(results, null, 2), function(err) {
        if(err) {
          console.log(err);
        } else {
          console.log("JSON saved to " + outputFilename);
        }
    });
  });