Membaca file teks menggunakan Node.js?


124

Saya harus memasukkan file teks ke terminal dan kemudian membaca data darinya, bagaimana saya bisa melakukan ini?

node server.js file.txt

Bagaimana cara saya melewati jalur dari terminal, bagaimana cara membacanya di sisi lain?


Jika Anda menemukan diri Anda menambahkan lebih banyak opsi pada baris perintah, Anda dapat menggunakan Optimist .
Jess

stackoverflow.com/questions/6156501/… menunjukkan cara lain untuk membaca file teks
Marc Durdin

Jawaban:


172

Anda akan ingin menggunakan process.argvarray untuk mengakses argumen baris perintah untuk mendapatkan nama file dan modul FileSystem (fs) untuk membaca file. Sebagai contoh:

// Make sure we got a filename on the command line.
if (process.argv.length < 3) {
  console.log('Usage: node ' + process.argv[1] + ' FILENAME');
  process.exit(1);
}
// Read the file and print its contents.
var fs = require('fs')
  , filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
  if (err) throw err;
  console.log('OK: ' + filename);
  console.log(data)
});

Untuk memecahnya sedikit untuk Anda process.argvbiasanya akan memiliki panjang dua, item ke nol adalah penerjemah "node" dan yang pertama adalah skrip yang saat ini dijalankan oleh node, item setelah itu diteruskan pada baris perintah. Setelah Anda menarik nama file dari argv maka Anda dapat menggunakan fungsi sistem file untuk membaca file dan melakukan apapun yang Anda inginkan dengan isinya. Penggunaan sampel akan terlihat seperti ini:

$ node ./cat.js file.txt
OK: file.txt
This is file.txt!

[Sunting] Seperti yang disebutkan @wtfcoder, menggunakan metode " fs.readFile()" mungkin bukan ide terbaik karena metode ini akan menyangga seluruh konten file sebelum menyerahkannya ke fungsi panggilan balik. Buffering ini berpotensi menggunakan banyak memori, tetapi yang lebih penting, buffering ini tidak memanfaatkan salah satu fitur inti node.js - asynchronous, evented I / O.

Cara "node" untuk memproses file besar (atau file apa pun, sebenarnya) akan menggunakan fs.read()dan memproses setiap potongan yang tersedia karena tersedia dari sistem operasi. Namun, membaca file seperti itu mengharuskan Anda untuk melakukan penguraian / pemrosesan tambahan sendiri (mungkin) file dan sejumlah buffering mungkin tidak terhindarkan.


Luar biasa, terima kasih banyak, sangat membantu. Bagaimana saya bisa membagi data ini dengan baris?
mewah

10
@fancy: coba var lines = data.split(/\r?\n/);, maka array "baris" akan memiliki setiap baris.
maerics

1
Ini bukan ide yang baik jika file teks besar, karena semuanya akan dibaca ke dalam memori, jika Anda memproses, katakanlah file CSV 1000mb, lihat fs.createFilestream, Anda harus berhati-hati dengan pemisahan baris meskipun sebagai potongan data tidak akan (dalam banyak kasus) jatuh pada batas garis (beberapa orang telah menemukan solusi - google)
Mâtt Frëman

1
@wtfcoder: ya, poin yang sangat bagus. Maksud saya hanya untuk mendemonstrasikan kasus sederhana membaca sebuah file bernama pada baris perintah; jelas ada banyak seluk-beluk (khususnya kinerja) yang berada di luar cakupan pertanyaan ini.
maerics

Saya memposting solusi untuk pertanyaan serupa untuk mem-parsing file yang sangat besar, menggunakan aliran, sinkron. lihat: stackoverflow.com/questions/16010915/…
Gerard

35

Gunakan fs dengan node.

var fs = require('fs');

try {  
    var data = fs.readFileSync('file.txt', 'utf8');
    console.log(data.toString());    
} catch(e) {
    console.log('Error:', e.stack);
}

Perhatikan bahwa ini adalah versi sinkron .
Rich Werden

@RichWerden Apa yang Anda maksud dengan "sinkron" dalam konteks ini?
Json

1
Dalam Node ketika ada sesuatu yang "sinkron", ia menghentikan / memblokir sistem untuk melakukan hal lain. Katakanlah Anda memiliki server web node - jika ada permintaan lain yang masuk saat hal di atas terjadi, server tidak akan / tidak dapat merespons karena sibuk membaca file.
Rich Werden

27

IMHO, fs.readFile()harus dihindari karena memuat SEMUA file di memori dan tidak akan memanggil callback sampai semua file telah dibaca.

Cara termudah untuk membaca file teks adalah dengan membacanya baris demi baris. Saya merekomendasikan BufferedReader :

new BufferedReader ("file", { encoding: "utf8" })
    .on ("error", function (error){
        console.log ("error: " + error);
    })
    .on ("line", function (line){
        console.log ("line: " + line);
    })
    .on ("end", function (){
        console.log ("EOF");
    })
    .read ();

Untuk struktur data yang kompleks seperti file .properties atau json, Anda perlu menggunakan parser (secara internal juga harus menggunakan pembaca buffer).


7
Terima kasih telah menunjukkan teknik ini. Anda benar bahwa ini mungkin cara terbaik, tetapi saya hanya berpikir ini sedikit membingungkan dalam konteks pertanyaan ini, yang menurut saya menanyakan tentang kasus penggunaan yang tidak menuntut. Seperti yang ditunjukkan di atas, jika itu hanya file kecil yang diteruskan ke alat baris perintah, tidak ada alasan untuk tidak menggunakan fs.readFile()atau fs.readFileSync(). Itu harus menjadi file besar untuk menyebabkan penantian yang nyata. Sebuah JSON file konfigurasi seperti package.json kemungkinan berada di bawah 1 kb, sehingga Anda dapat hanya fs.readFile()dan JSON.parse()itu.
John Starr Dewar

1
BufferedReader mungkin telah mengubah tanda tangannya. Saya harus mengganti BufferedReader dengan BufferedReader, DataReader, di mana BufferedReader adalah modulnya. Lihat github.com/Gagle/Node-BufferedReader
bnieland

13
Saya melihat BufferedReader sekarang tidak digunakan lagi.
Marc Rochkind

6

Anda dapat menggunakan readstream dan pipe untuk membaca file baris demi baris tanpa membaca semua file ke dalam memori satu kali.

var fs = require('fs'),
    es = require('event-stream'),
    os = require('os');

var s = fs.createReadStream(path)
    .pipe(es.split())
    .pipe(es.mapSync(function(line) {
        //pause the readstream
        s.pause();
        console.log("line:", line);
        s.resume();
    })
    .on('error', function(err) {
        console.log('Error:', err);
    })
    .on('end', function() {
        console.log('Finish reading.');
    })
);

5

Saya memposting contoh lengkap yang akhirnya saya kerjakan. Di sini saya membaca file rooms/rooms.txtdari skriprooms/rooms.js

var fs = require('fs');
var path = require('path');
var readStream = fs.createReadStream(path.join(__dirname, '../rooms') + '/rooms.txt', 'utf8');
let data = ''
readStream.on('data', function(chunk) {
    data += chunk;
}).on('end', function() {
    console.log(data);
});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.