Fichiers et chemins avec fs et path
node:fs/promises et node:path en conditions réelles.
Objectifs
À la fin de cette leçon, vous saurez :
- lire et écrire des fichiers avec node:fs ;
- composer des chemins portables avec node:path ;
- choisir entre versions synchrones, callbacks et promises.
🔗 Pour vous rafraîchir la mémoire : l'event loop
Importer les modules natifs
const fs = require("node:fs"); // style CommonJS (historique)
// ou
import fs from "node:fs"; // style ESM (moderne)
Le préfixe node: explicite « module natif » : adoptez-le systématiquement.
Écrire puis lire
import { writeFileSync, readFileSync } from "node:fs";
writeFileSync("journal.txt", "Première entrée\n");
const contenu = readFileSync("journal.txt", "utf8");
console.log(contenu);
Sans l'encodage "utf8", readFileSync renvoie un Buffer (octets bruts) : c'est la cause classique d'un affichage <Buffer 50 61 ...>.
La version promise : le standard moderne
import { readFile, writeFile } from "node:fs/promises";
async function journaliser(texte) {
const ancien = await readFile("journal.txt", "utf8").catch(() => "");
await writeFile("journal.txt", ancien + texte + "\n");
}
.catch(() => "") absorbe proprement le cas « fichier pas encore créé ». Préférez cette API async partout : elle ne bloque pas l'event loop — vital dès que votre serveur servira plusieurs clients.
Les chemins avec path
Concaténer des chaînes pour faire des chemins casse sur Windows (\) vs Linux (/). path.join produit le bon séparateur :
import { join } from "node:path";
const dossier = join(__dirname, "donnees");
const fichier = join(dossier, "journal.txt");
// Linux : /home/cours/projet/donnees/journal.txt
// Windows: C:\projet\donnees\journal.txt
Compléments utiles : path.basename(fichier) (nom seul), path.extname(fichier) (extension), mkdirSync(dossier, { recursive: true }) (créer l'arborescence).
Exercice
- Créez un script qui écrit trois lignes dans
courses.txtpuis les relit en majuscules. - Faites une version async de ce script.
- Construisez avec
joinle chemin d'un fichier dans un sous-dossier créé récursivement. - Que se passe-t-il si vous relisez sans
"utf8"?
Résumé
node:fs/promises+ async/await = le duo par défaut.- Toujours préciser
"utf8"pour du texte. path.joinrend les chemins portables ;__dirnameancre au fichier courant.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 2.
import { readFile, writeFile } from "node:fs/promises";
await writeFile("courses.txt", "pain\nlait\nœufs\n");
const contenu = await readFile("courses.txt", "utf8");
console.log(contenu.toUpperCase());
Question 4. Vous recevez un Buffer ; .toUpperCase() échoue (méthode inexistante) ou affiche des octets hexadécimaux selon l'usage. Le Buffer reste utile pour les binaires (images) — pour du texte, exigez toujours l'encodage.