Saya perlu melakukan beberapa parsing file log besar (5-10 Gb) di Javascript / Node.js (Saya menggunakan Cube).
Logline terlihat seperti ini:
10:00:43.343423 I'm a friendly log message. There are 5 cats, and 7 dogs. We are in state "SUCCESS".
Kita perlu membaca setiap baris, melakukan beberapa parsing (misalnya strip out 5
, 7
dan SUCCESS
), lalu memompa data ini ke dalam Cube ( https://github.com/square/cube ) menggunakan klien JS mereka.
Pertama, apa cara kanonik di Node untuk membaca dalam file, baris demi baris?
Tampaknya pertanyaan online yang cukup umum:
- http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
- Membaca file satu baris dalam satu waktu di node.js?
Banyak jawaban yang tampaknya mengarah ke sekumpulan modul pihak ketiga:
- https://github.com/nickewing/line-reader
- https://github.com/jahewson/node-byline
- https://github.com/pkrumins/node-lazy
- https://github.com/Gagle/Node-BufferedReader
Namun, ini tampak seperti tugas yang cukup mendasar - tentunya, ada cara sederhana dalam stdlib untuk membaca dalam file teks, baris demi baris?
Kedua, saya kemudian perlu memproses setiap baris (misalnya mengubah cap waktu menjadi objek Tanggal, dan mengekstrak bidang yang berguna).
Apa cara terbaik untuk melakukan ini, memaksimalkan hasil? Adakah cara yang tidak akan memblokir pembacaan di setiap baris, atau saat mengirimkannya ke Cube?
Ketiga - Saya menebak menggunakan pemisahan string, dan JS yang setara dengan berisi (IndexOf! = -1?) Akan jauh lebih cepat daripada regex? Adakah yang punya banyak pengalaman dalam mengurai sejumlah besar data teks di Node.js?
Cheers, Victor
sumber
Jawaban:
Saya mencari solusi untuk mengurai file yang sangat besar (gbs) baris demi baris menggunakan aliran. Semua pustaka dan contoh pihak ketiga tidak sesuai dengan kebutuhan saya karena mereka memproses file tidak baris demi baris (seperti 1, 2, 3, 4 ..) atau membaca seluruh file ke memori
Solusi berikut dapat mengurai file yang sangat besar, baris demi baris menggunakan aliran & pipa. Untuk pengujian saya menggunakan file 2.1 gb dengan 17.000.000 catatan. Penggunaan ram tidak melebihi 60 mb.
Pertama, instal paket aliran acara :
Kemudian:
Tolong beritahu saya bagaimana kelanjutannya!
sumber
console.log(lineNr)
setelah baris terakhir kode Anda, itu tidak akan menampilkan jumlah baris terakhir karena file dibaca secara asynchronous.s.end();
readline
modul adalah rasa sakit. Itu tidak berhenti dan selalu menyebabkan kegagalan setelah 40-50 juta. Membuang satu hari. Terima kasih banyak atas jawabannya. Yang ini bekerja dengan sempurnaAnda dapat menggunakan
readline
paket bawaan , lihat dokumen di sini . Saya menggunakan aliran untuk membuat aliran keluaran baru.File besar akan membutuhkan waktu untuk diproses. Beri tahu apakah itu berhasil.
sumber
readline
, apakah mungkin untuk menjeda / melanjutkan aliran baca untuk melakukan tindakan asinkron di area "lakukan barang"?readline
memberi saya banyak masalah ketika saya mencoba jeda / melanjutkan. Itu tidak menghentikan aliran dengan benar menciptakan banyak masalah jika proses hilir lebih lambatSaya sangat menyukai jawaban @gerard yang sebenarnya pantas menjadi jawaban yang benar di sini. Saya membuat beberapa perbaikan:
Berikut kodenya:
Jadi pada dasarnya, inilah cara Anda menggunakannya:
Saya menguji ini dengan file CSV 35GB dan itu berhasil untuk saya dan itulah mengapa saya memilih untuk membangunnya berdasarkan jawaban @gerard , umpan balik disambut.
sumber
pause()
panggilan, bukan?Saya menggunakan https://www.npmjs.com/package/line-by-line untuk membaca lebih dari 1.000.000 baris dari file teks. Dalam hal ini, kapasitas RAM yang terisi sekitar 50-60 megabyte.
sumber
lr.cancel()
metode. Membaca 1000 baris pertama dari file 5Gig dalam 1ms. Luar biasa !!!!Selain membaca file besar baris demi baris, Anda juga dapat membacanya potongan demi potongan. Untuk lebih lanjut lihat artikel ini
sumber
if(bytesRead = chunkSize)
?Dokumentasi Node.js menawarkan contoh yang sangat elegan menggunakan modul Readline.
Contoh: Baca Aliran File Baris demi Baris
sumber
Saya memiliki masalah yang sama. Setelah membandingkan beberapa modul yang tampaknya memiliki fitur ini, saya memutuskan untuk melakukannya sendiri, ini lebih sederhana dari yang saya kira.
intinya: https://gist.github.com/deemstone/8279565
Ini mencakup file yang dibuka dalam penutupan, yang
fetchBlock()
dikembalikan akan mengambil blok dari file, dan berakhir dibagi menjadi array (akan menangani segmen dari pengambilan terakhir).Saya telah mengatur ukuran blok menjadi 1024 untuk setiap operasi baca. Ini mungkin memiliki bug, tetapi logika kodenya jelas, coba sendiri.
sumber
node-byline menggunakan aliran, jadi saya lebih suka yang itu untuk file besar Anda.
untuk konversi tanggal Anda, saya akan menggunakan moment.js .
untuk memaksimalkan throughput Anda, Anda dapat memikirkan tentang menggunakan cluster perangkat lunak. ada beberapa nice-modules yang membungkus cluster-module node-native dengan cukup baik. saya suka cluster-master dari isaacs. misalnya Anda bisa membuat sebuah cluster x pekerja yang semuanya menghitung sebuah file.
untuk benchmarking split vs regexes gunakan benchmark.js . saya belum mengujinya sampai sekarang. benchmark.js tersedia sebagai modul-node
sumber
Berdasarkan jawaban pertanyaan ini , saya menerapkan kelas yang dapat Anda gunakan untuk membaca file secara sinkron baris demi baris
fs.readSync()
. Anda bisa membuat ini "pause" dan "resume" dengan menggunakan sebuahQ
promise (jQuery
sepertinya membutuhkan DOM jadi tidak bisa menjalankannya dengannodejs
):sumber
sumber
Saya telah membuat modul node untuk membaca file besar teks asinkron atau JSON. Diuji pada file besar.
Simpan saja file tersebut sebagai file-reader.js, dan gunakan seperti ini:
sumber