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

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

first line
two 
three
...
...

我有一个数组:

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

函数看起来是这样的:

var array = load(filename); 

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


当前回答

另一个答案是使用npm包。nexline包允许用户逐行异步读取文件:

"use strict";

import fs from 'fs';
import nexline from 'nexline';

const lines = [];
const reader = nexline({
    input: fs.createReadStream(`path/to/file.ext`)
});

while(true) {
    const line = await reader.next();
    if(line === null) break; // line is null if we reach the end
    if(line.length === 0) continue; // Ignore empty lines
    
    // Process the line here - below is just an example
    lines.push(line);
}

即使您的文本文件大于允许的最大字符串长度,这种方法也可以工作,从而避免“错误:不能创建超过0x1fffffe8个字符的字符串”错误。

其他回答

另一个答案是使用npm包。nexline包允许用户逐行异步读取文件:

"use strict";

import fs from 'fs';
import nexline from 'nexline';

const lines = [];
const reader = nexline({
    input: fs.createReadStream(`path/to/file.ext`)
});

while(true) {
    const line = await reader.next();
    if(line === null) break; // line is null if we reach the end
    if(line.length === 0) continue; // Ignore empty lines
    
    // Process the line here - below is just an example
    lines.push(line);
}

即使您的文本文件大于允许的最大字符串长度,这种方法也可以工作,从而避免“错误:不能创建超过0x1fffffe8个字符的字符串”错误。

使用BufferedReader,但函数应该是异步的:

var load = function (file, cb){
    var lines = [];
    new BufferedReader (file, { encoding: "utf8" })
        .on ("error", function (error){
            cb (error, null);
        })
        .on ("line", function (line){
            lines.push (line);
        })
        .on ("end", function (){
            cb (null, lines);
        })
        .read ();
};

load ("file", function (error, lines){
    if (error) return console.log (error);
    console.log (lines);
});

js:

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

ts:

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

这是@mtomis上面回答的一个变体。

它创建了一个行流。它发出'data'和'end'事件,允许您处理流的结束。

var events = require('events');

var LineStream = function (input) {
    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;
            this.emit('data', line);
            index = remaining.indexOf('\n', last);
        }
        remaining = remaining.substring(last);
    }.bind(this));

    input.on('end', function() {
        if (remaining.length > 0) {
            this.emit('data', remaining);
        }
        this.emit('end');
    }.bind(this));
}

LineStream.prototype = new events.EventEmitter;

用它来包装:

var lineInput = new LineStream(input);

lineInput.on('data', function (line) {
    // handle line
});

lineInput.on('end', function() {
    // wrap it up
});

我有同样的问题,我已经解决了它与模块逐行

https://www.npmjs.com/package/line-by-line

至少对我来说,无论是在同步模式还是异步模式下,它都很有魅力。

同样,行终止不终止\n的问题可以用选项解决:

{ encoding: 'utf8', skipEmptyLines: false }

行同步处理:

var LineByLineReader = require('line-by-line'),
    lr = new LineByLineReader('big_file.txt');

lr.on('error', function (err) {
    // 'err' contains error object
});

lr.on('line', function (line) {
    // 'line' contains the current line without the trailing newline character.
});

lr.on('end', function () {
    // All lines are read, file is closed now.
});