Week 6 - Advanced topics

Synchronous File IO

File processing

Error handling

Array methods

Closures

Style - How to write meaningful comments

Practice

Assignment

Core program

What is File I/O?

File I/O (Input/Output) lets your programs read from and write to files on your computer. This enables data persistence: your program can save data and reload it later.

Node.js provides the fs (filesystem) module for file operations. We'll focus on synchronous methods, which pause your program until the file operation completes.

import fs from 'node:fs';

// Synchronous - waits for file to be read
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);
console.log('This runs after reading');

<aside> 💡

"Synchronous" means blocking: your code waits.

</aside>

Reading Files

readFileSync()

import fs from 'node:fs';

// Read entire file as string
const content = fs.readFileSync('data.txt', 'utf8');
console.log(content);

// Without 'utf8', returns Buffer (raw bytes)
const buffer = fs.readFileSync('data.txt');
console.log(buffer); // <Buffer 48 65 6c 6c 6f>

Parameters:

Common use cases:

// Read configuration
const config = fs.readFileSync('config.txt', 'utf8');

// Read user data
const users = fs.readFileSync('users.txt', 'utf8');

// Process line by line
const lines = fs.readFileSync('data.txt', 'utf8').split('\\\\n');
for (const line of lines) {
  console.log(line);
}

<aside> ⌨️

Hands on: Create a file called message.txt with some text. Write code to read and print its contents.

</aside>

existsSync()

Check if a file exists before reading:

if (fs.existsSync('data.txt')) {
  const data = fs.readFileSync('data.txt', 'utf8');
  console.log(data);
} else {
  console.log('File not found');
}

Writing files

writeFileSync()

import fs from 'node:fs';

// Write string to file (overwrites existing content)
fs.writeFileSync('output.txt', 'Hello, World!');

// Write multiple lines
const lines = ['Line 1', 'Line 2', 'Line 3'];
fs.writeFileSync('output.txt', lines.join('\\\\n'));

Important: writeFileSync() overwrites the entire file. Previous content is lost.

// Example: save user data
const user = {
  name: 'Alice',
  age: 28
};
fs.writeFileSync('user.txt', JSON.stringify(user, null, 2));

<aside> ⚠️

Always include error handling (covered in upcoming sections) when working with files. File operations can fail if the file doesn't exist, lacks permissions, or the disk is full.

</aside>

appendFileSync()

Add content to the end of a file without erasing existing content:

import fs from 'node:fs';

// Append to existing file
fs.appendFileSync('log.txt', 'New log entry\\\\n');

// Create file if it doesn't exist
if (!fs.existsSync('notes.txt')) {
  fs.writeFileSync('notes.txt', '');
}
fs.appendFileSync('notes.txt', 'First note\\\\n');
fs.appendFileSync('notes.txt', 'Second note\\\\n');

Common use case - logging:

function log(message) {
  const timestamp = new Date().toISOString();
  fs.appendFileSync('app.log', `[${timestamp}] ${message}\\\\n`);
}

log('Application started');
log('User logged in');
log('Error occurred');

File Paths

Relative vs Absolute Paths

// Relative to current working directory
fs.readFileSync('data.txt', 'utf8');
fs.readFileSync('./data.txt', 'utf8');
fs.readFileSync('../data.txt', 'utf8');

// Absolute path
fs.readFileSync('/Users/alice/projects/data.txt', 'utf8');
fs.readFileSync('C:\\\\\\\\Users\\\\\\\\alice\\\\\\\\projects\\\\\\\\data.txt', 'utf8'); // Windows

Using __dirname

__dirname gives the directory of the current file (not the working directory):

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

// In ES modules, we need to recreate __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Build path relative to script location
const filePath = path.join(__dirname, 'data.txt');
const data = fs.readFileSync(filePath, 'utf8');

// Nested folders
const configPath = path.join(__dirname, 'config', 'settings.txt');

<aside> 💡

Use path.join() to build paths—it handles different operating systems automatically (/ on Mac/Linux, \ on Windows).

</aside>

Practical Examples

Example 1: Simple Todo List

import fs from 'node:fs';

const todos = ['Buy groceries', 'Walk dog', 'Write code'];

// Save todos
fs.writeFileSync('todos.txt', todos.join('\\\\n'));

// Load todos
const loadedTodos = fs.readFileSync('todos.txt', 'utf8').split('\\\\n');
console.log(loadedTodos);

Example 2: Word Counter

import fs from 'node:fs';

const text = fs.readFileSync('article.txt', 'utf8');
const words = text.split(/\\\\s+/); // Split on whitespace
const wordCount = words.length;

console.log(`Word count: ${wordCount}`);
fs.writeFileSync('word-count.txt', `Total words: ${wordCount}`);

Example 3: Data Backup

import fs from 'node:fs';

function backup(filename) {
  if (fs.existsSync(filename)) {
    const content = fs.readFileSync(filename, 'utf8');
    const backupName = `${filename}.backup`;
    fs.writeFileSync(backupName, content);
    console.log(`Backed up ${filename} to ${backupName}`);
  }
}

backup('important-data.txt');

<aside> ⌨️

Hands on: Create a program that reads a text file, counts how many times the word "JavaScript" appears, and writes the count to a new file.

</aside>

Common Patterns

Read-Process-Write Pattern

import fs from 'node:fs';

// 1. Read
const input = fs.readFileSync('input.txt', 'utf8');

// 2. Process
const processed = input.toUpperCase();

// 3. Write
fs.writeFileSync('output.txt', processed);

Working with Lines

import fs from 'node:fs';

// Read all lines
const lines = fs.readFileSync('data.txt', 'utf8').split('\\\\n');

// Filter empty lines
const nonEmpty = lines.filter(line => line.trim() !== '');

// Process each line
const processed = nonEmpty.map(line => line.trim().toUpperCase());

// Write back
fs.writeFileSync('cleaned.txt', processed.join('\\\\n'));

Summary

Method Purpose Overwrites?
readFileSync(path, encoding) Read entire file -
writeFileSync(path, data) Write to file Yes
appendFileSync(path, data) Add to end of file No
existsSync(path) Check if file exists -

Additional resources

Video

Reading


CC BY-NC-SA 4.0 Icons

*https://hackyourfuture.net/*

Found a mistake or have a suggestion? Let us know in the feedback form.