我想把一个非常非常大的文件读入node。js中的JavaScript数组。
所以,如果文件是这样的:
first line
two
three
...
...
我有一个数组:
['first line','two','three', ... , ... ]
函数看起来是这样的:
var array = load(filename);
因此,将其全部作为字符串加载,然后将其拆分的想法是不可接受的。
我想把一个非常非常大的文件读入node。js中的JavaScript数组。
所以,如果文件是这样的:
first line
two
three
...
...
我有一个数组:
['first line','two','three', ... , ... ]
函数看起来是这样的:
var array = load(filename);
因此,将其全部作为字符串加载,然后将其拆分的想法是不可接受的。
当前回答
使用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);
}
});
});
其他回答
另一个答案是使用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个字符的字符串”错误。
本质上,这将完成工作:.replace(/\r\n/g,'\n').split('\n')。 这适用于Mac, Linux和Windows。
代码片段
同步:
const { readFileSync } = require('fs');
const array = readFileSync('file.txt').toString().replace(/\r\n/g,'\n').split('\n');
for(let i of array) {
console.log(i);
}
异步:
用fs。promises API提供了另一组异步文件系统方法,返回Promise对象而不是使用回调。(不需要承诺,你也可以使用async-await,在Node.js 10.0.0版本之后可用)
const { readFile } = require('fs').promises;
readFile('file.txt', function(err, data) {
if(err) throw err;
const arr = data.toString().replace(/\r\n/g,'\n').split('\n');
for(let i of arr) {
console.log(i);
}
});
更多关于\r和\n的信息在这里:\r\n, \r和\n它们之间有什么区别?
我只是想添加@finbarr伟大的答案,在异步的例子中的一个小修复:
异步:
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]);
}
done();
});
@ madphysics, done()释放async。调用。
使用Node.js v8或更高版本有一个新特性,可以将普通函数转换为异步函数。
util.promisify
这是一个很棒的功能。下面是将txt文件中的10000个数字解析为一个数组的示例,使用归并排序对数字进行逆序计数。
// read from txt file
const util = require('util');
const fs = require('fs')
fs.readFileAsync = util.promisify(fs.readFile);
let result = []
const parseTxt = async (csvFile) => {
let fields, obj
const data = await fs.readFileAsync(csvFile)
const str = data.toString()
const lines = str.split('\r\n')
// const lines = str
console.log("lines", lines)
// console.log("str", str)
lines.map(line => {
if(!line) {return null}
result.push(Number(line))
})
console.log("result",result)
return result
}
parseTxt('./count-inversion.txt').then(() => {
console.log(mergeSort({arr: result, count: 0}))
})
使用Node.js的readline模块。
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);
});