Reading Files
Reading a file is the most common filesystem task, and Node gives you several tools for it — readFile for whole files, streams for large ones, and readline for line-by-line processing. Choosing correctly comes down to one question: how big is the file, and do you need it all at once?
Read an entire file
import { readFile } from 'node:fs/promises'
// As text — pass an encoding:
const text = await readFile('notes.txt', 'utf8')
// As raw bytes — omit the encoding to get a Buffer:
const bytes = await readFile('photo.jpg')
console.log(text.length, 'chars;', bytes.length, 'bytes')Reading and parsing JSON
A constant need. Read the text, then JSON.parse — and wrap it so a malformed file gives a clear error instead of a cryptic one:
import { readFile } from 'node:fs/promises'
async function readJSON(path) {
const text = await readFile(path, 'utf8')
try {
return JSON.parse(text)
} catch {
throw new Error(`Invalid JSON in ${path}`)
}
}
const config = await readJSON('config.json')Handling the missing-file case
import { readFile } from 'node:fs/promises'
async function readOrDefault(path, fallback) {
try {
return await readFile(path, 'utf8')
} catch (err) {
if (err.code === 'ENOENT') return fallback // expected: use default
throw err // unexpected: propagate
}
}Large files: stream, don't buffer
import { createReadStream } from 'node:fs'
const stream = createReadStream('huge.log', { encoding: 'utf8' })
stream.on('data', (chunk) => process.stdout.write(chunk)) // chunk by chunk
stream.on('end', () => console.log('\n--- done ---'))
stream.on('error', (err) => console.error('read failed:', err.code))Streams are covered fully in Readable Streams.
Line by line with readline
To process a big text file one line at a time — logs, CSVs — combine a read stream with readline and for await. This never holds more than one line in memory:
import { createReadStream } from 'node:fs'
import { createInterface } from 'node:readline'
const rl = createInterface({
input: createReadStream('access.log'),
crlfDelay: Infinity, // treat \r\n as one line break
})
let count = 0
for await (const line of rl) {
if (line.includes('ERROR')) count++
}
console.log(`${count} error lines`)Choosing the right tool
Situation | Use |
|---|---|
Small file, need it all |
|
Static JSON bundled with code |
|
Large file, process in chunks |
|
Large text, work line by line |
|
Copy file to file |
|