Menu

fs.readFile Node.js: Membaca File (Sync, Async, Promise)

Baca file di Node.js dengan fs.readFile (callback), fs.readFileSync, atau await readFile dari fs/promises. Berikan 'utf8' untuk mendapat string, dan tangani ENOENT saat file tidak ada.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

fs.readFile(path, 'utf8', callback) membaca seluruh file dan memberikan isinya ke callback sebagai string. fs.readFileSync(path, 'utf8') langsung mengembalikan string-nya dan menunggu sampai pembacaan selesai, sedangkan await readFile(path, 'utf8') dari fs/promises melakukan hal yang sama tanpa memblokir. Kalau 'utf8' dihilangkan, kamu mendapat Buffer berisi byte mentah, bukan teks.

readFile called tercetak lebih dulu: readFile hanya memulai pembacaan, dan callback-nya berjalan setelah isi file siap. Hapus 'utf8', lalu jalankan lagi: callback menerima <Buffer 42 75 79 20 6d 69 6c 6b 0a 43 61 6c 6c 20 41 64 61>, byte mentah dari file itu.

readFile vs readFileSync vs fs/promises

Ketiganya membaca file yang sama. Bedanya ada pada cara kamu mendapat hasilnya dan apakah sisa program ikut menunggu.

Baris sync tercetak lebih dulu karena tidak ada hal lain yang berjalan sampai ia kembali. Dua lainnya selesai setelah kode utama, dengan urutan sesuai pembacaan mana yang selesai duluan.

readFileSyncreadFile (callback)fs/promises readFile
MengembalikanIsi fileundefinedPromise berisi isi file
Memblokir programYaTidakTidak
ErrorDilempar, pakai try/catchArgumen pertama callbackPromise reject, try/catch dengan await
Dipakai diKode startup dan scriptKode callback lamaKode baru

Pakai readFileSync saat membaca config ketika startup atau di script pendek. Di server, pembacaan sync menghentikan setiap request lain selama disk bekerja, jadi pakai versi promise di sana. Halaman fs/promises membahas sisa API tersebut.

Menangani file yang tidak ada (ENOENT)

Saat file tidak ada, error-nya punya code: 'ENOENT' ("error, no entry"). Cek err.code untuk membedakan file yang tidak ada dari kegagalan lain, seperti masalah izin akses.

Panggilan pertama tidak menemukan file dan kembali ke default settings; panggilan kedua membaca dark mode. Melempar ulang error lainnya membuat masalah sungguhan tetap terlihat, alih-alih diam-diam memakai nilai default.

fs.existsSync: kenapa sebaiknya langsung coba membaca

fs.existsSync(path) mengembalikan true atau false, dan rasanya menggoda untuk mengecek dulu sebelum membaca:

if (fs.existsSync('data.txt')) {
    const text = fs.readFileSync('data.txt', 'utf8');
}

Itu dua langkah padahal satu sudah cukup, dan file bisa saja dihapus di antara keduanya, jadi pembacaan tetap bisa melempar error. Coba baca langsung dan tangani ENOENT, seperti di atas. existsSync cocok saat kamu hanya perlu tahu apakah sesuatu ada dan tidak akan membukanya, misalnya untuk memutuskan apakah perlu membuat folder.

Membaca file JSON

Baca teksnya, lalu parse dengan JSON.parse. File dengan kesalahan sintaks melempar SyntaxError, jadi letakkan di dalam try yang sama.

Hasilnya 3001 dan boolean: setelah di-parse, nilai-nilainya punya tipe JSON masing-masing. require('./config.json') juga bisa, tetapi hasilnya di-cache, jadi require kedua mengembalikan object lama walaupun file-nya sudah berubah.

Membaca file per baris

Untuk file yang muat di memori, baca seluruhnya lalu split di karakter newline. Buang string kosong yang tersisa karena newline di akhir file.

Split menghasilkan 4 item, yang terakhir kosong, jadi perulangannya mencetak tiga baris bernomor. File yang ditulis di Windows mengakhiri baris dengan \r\n; split dengan /\r?\n/ untuk menangani keduanya.

Log berukuran beberapa gigabyte tidak muat di memori. Stream saja, supaya hanya satu baris yang disimpan dalam satu waktu:

const fs = require('fs');
const readline = require('readline');

async function main() {
    const rl = readline.createInterface({
        input: fs.createReadStream('big.log'),
        crlfDelay: Infinity,
    });
    for await (const line of rl) {
        console.log(line);
    }
}
main();

Kesalahan umum

Memakai hasilnya di luar callback. const text = fs.readFile(...) bernilai undefined. Isi file hanya ada di dalam callback, atau setelah await.

Lupa encoding. Tanpa 'utf8' kamu mendapat Buffer, dan data.split('\n') melempar data.split is not a function. Berikan encoding setiap kali kamu menginginkan teks.

Path relatif ke folder yang salah. 'data.txt' dicari di tempat node dijalankan. Pakai path.join(__dirname, 'data.txt') untuk file yang disertakan di samping script-mu.

Pertanyaan yang sering diajukan

Kenapa fs.readFile mengembalikan undefined?

fs.readFile tidak mengembalikan isi file. Fungsi ini memulai pembacaan dan memanggil callback-mu belakangan dengan (err, data). Pakai datanya di dalam callback, panggil readFileSync, atau await versi promise-nya.

Di mana Node mencari path relatif seperti 'data.txt'?

Di current working directory, yaitu folder tempat kamu menjalankan node, bukan folder script-nya. Untuk membaca file yang ada di samping script, susun path-nya dengan path.join(__dirname, 'data.txt').

Bisakah fs.readFile membaca file dari URL?

Tidak, fungsi ini hanya membaca dari file system. Untuk mengambil file lewat HTTP, pakai fetch lalu await res.text().

Seberapa besar file yang bisa ditangani readFile?

Fungsi ini memuat seluruh file ke memori, jadi cocok untuk config, template, dan file data kecil. Untuk file berukuran ratusan megabyte, baca per bagian dengan fs.createReadStream.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai