Giả sử bạn có một rất lớn (> 1GB) CSV của id kỷ lục:Làm thế nào để chạy một chức năng async cho mỗi dòng một (> 1GB) tập tin rất lớn trong Node.js
655453
4930285
493029
4930301
493031
...
Và đối với mỗi id
bạn muốn thực hiện cuộc gọi REST API để tìm nạp dữ liệu bản ghi, chuyển đổi nó cục bộ và chèn nó vào một cơ sở dữ liệu cục bộ.
Bạn làm như thế nào với Node.js 'Readable Stream
?
Câu hỏi của tôi về cơ bản là: Làm thế nào để bạn đọc một tệp rất lớn, từng dòng một, chạy một hàm async cho mỗi dòng và [tùy chọn] có thể bắt đầu đọc tệp từ một dòng cụ thể?
Từ câu hỏi Quora sau tôi bắt đầu học cách sử dụng fs.createReadStream
:
http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
var fs = require('fs');
var lazy = require('lazy');
var stream = fs.createReadStream(path, {
flags: 'r',
encoding: 'utf-8'
});
new lazy(stream).lines.forEach(function(line) {
var id = line.toString();
// pause stream
stream.pause();
// make async API call...
makeAPICall(id, function() {
// then resume to process next id
stream.resume();
});
});
Nhưng, giả đó không làm việc, bởi vì lazy
module buộc bạn phải đọc toàn bộ tập tin (dưới dạng luồng, nhưng không có tạm dừng). Cách tiếp cận đó dường như không hoạt động.
Một điều nữa là, tôi muốn có thể bắt đầu xử lý tệp này từ một dòng cụ thể. Lý do cho việc này là, xử lý mỗi id
(thực hiện cuộc gọi api, làm sạch dữ liệu, v.v.) có thể mất đến nửa giây cho mỗi bản ghi vì vậy tôi không muốn phải bắt đầu từ đầu tệp mỗi lần . Cách tiếp cận ngây thơ tôi đang nghĩ đến việc sử dụng là chỉ cần nắm bắt số dòng của id cuối cùng được xử lý và lưu lại. Sau đó, khi bạn phân tích cú pháp tệp một lần nữa, bạn truyền qua tất cả các id, từng dòng một, cho đến khi bạn tìm thấy số dòng bạn đã dừng lại, và sau đó bạn thực hiện công việc kinh doanh makeAPICall
. Một cách tiếp cận ngây thơ khác là viết các tệp nhỏ (nói 100 id) và xử lý từng tệp một lúc (bộ dữ liệu đủ nhỏ để thực hiện mọi thứ trong bộ nhớ mà không có luồng IO). Có cách nào tốt hơn để làm điều này?
tôi có thể thấy cách này được khôn lanh (và nơi node-lazy do thỏa thuận hợp) vì chunk
trong stream.on('data', function(chunk) {});
có thể chứa chỉ phần của một dòng (nếu BUFFERSIZE là nhỏ, mỗi đoạn có thể 10 dòng nhưng vì id
là độ dài thay đổi, nó chỉ có thể là 9,5 dòng hoặc bất cứ điều gì). Đây là lý do tại sao tôi tự hỏi cách tiếp cận tốt nhất là gì đối với câu hỏi trên.
đoán đây là những gì redis và việc làm nền dành cho ... –
bắt đầu nhìn đầy hứa hẹn: https://gist.github.com/2947293 –
tôi đăng một giải pháp cho một câu hỏi tương tự cho phân tích rất lớn tệp, sử dụng luồng, đồng bộ. xem: http://stackoverflow.com/questions/16010915/parsing-huge-logfiles-in-node-js-read-in-line-by-line/23695940#23695940 – Gerard