Như Robbie đã nói, suối là cách để thực hiện điều này. fs.createReadStream()
nên được sử dụng thay vì .readFileSync()
. Tôi sẽ bắt đầu với việc tạo một trình đọc dòng có một đường dẫn và bất kỳ chuỗi / regex nào bạn muốn tách:
linereader.js
var fs = require("fs");
var util = require("util");
var EventEmitter = require("events").EventEmitter;
function LineReader(path, splitOn) {
var readStream = fs.createReadStream(path);
var self = this;
var lineNum = 0;
var buff = ""
var chunk;
readStream.on("readable", function() {
while( (chunk = readStream.read(100)) !== null) {
buff += chunk.toString();
var lines = buff.split(splitOn);
for (var i = 0; i < lines.length - 1; i++) {
self.emit("line",lines[i]);
lineNum += 1;
}
buff = lines[lines.length - 1];
}
});
readStream.on("close", function() {
self.emit("line", buff);
self.emit("close")
});
readStream.on("error", function(err) {
self.emit("error", err);
})
}
util.inherits(LineReader, EventEmitter);
module.exports = LineReader;
Thao tác này sẽ đọc một tệp văn bản và phát ra các sự kiện "dòng" cho mỗi dòng được đọc, vì vậy bạn sẽ không có tất cả chúng trong bộ nhớ cùng một lúc. Sau đó, sử dụng gói không đồng bộ (hoặc bất kỳ vòng lặp không đồng bộ nào bạn muốn sử dụng), lặp qua các tệp chèn từng tài liệu:
app.js
var LineReader = require("./linereader.js");
var async = require("async");
var paths = ["./text1.txt", "./text2.txt", "./path1/text3.txt"];
var reader;
async.eachSeries(paths, function(path, callback) {
reader = new LineReader(path, /\n/g);
reader.on("line", function(line) {
var doc = turnTextIntoObject(line);
db.collection("mycollection").insert(doc);
})
reader.on("close", callback);
reader.on("error", callback);
}, function(err) {
// handle error and finish;
})