fs.readFile(path, 'utf8', callback) lit un fichier entier et passe son contenu au callback sous forme de chaîne. fs.readFileSync(path, 'utf8') renvoie directement la chaîne et attend la fin de la lecture, et await readFile(path, 'utf8') de fs/promises fait la même chose sans bloquer. Sans 'utf8', vous obtenez un Buffer d'octets bruts au lieu de texte.
readFile called s'affiche en premier : readFile ne fait que lancer la lecture, et le callback s'exécute une fois le contenu prêt. Supprimez 'utf8', et relancez : le callback reçoit <Buffer 42 75 79 20 6d 69 6c 6b 0a 43 61 6c 6c 20 41 64 61>, les octets bruts du fichier.
readFile, readFileSync ou fs/promises
Les trois lisent le même fichier. Ils diffèrent par la façon d'obtenir le résultat et par le fait que le reste du programme attende ou non.
La ligne synchrone s'affiche en premier, car rien d'autre ne s'exécute avant son retour. Les deux autres se terminent après le code principal, dans l'ordre où leurs lectures aboutissent.
readFileSync | readFile (callback) | readFile de fs/promises | |
|---|---|---|---|
| Renvoie | Le contenu | undefined | Une promesse du contenu |
| Bloque le programme | Oui | Non | Non |
| Erreurs | Levées, utilisez try/catch | Premier argument du callback | Promesse rejetée, try/catch avec await |
| À utiliser dans | Le code de démarrage et les scripts | L'ancien code à callbacks | Le nouveau code |
Utilisez readFileSync pour lire une config au démarrage ou dans un petit script. Dans un serveur, une lecture synchrone arrête toutes les autres requêtes pendant que le disque travaille, donc utilisez-y la version à promesses. La page sur fs/promises couvre le reste de cette API.
Gérer un fichier absent (ENOENT)
Quand le fichier n'existe pas, l'erreur a code: 'ENOENT' ("error, no entry"). Vérifiez err.code pour distinguer un fichier manquant des autres échecs, comme un problème de permissions.
Le premier appel ne trouve pas de fichier et se rabat sur default settings ; le second lit dark mode. Relancer les autres erreurs garde les vrais problèmes visibles au lieu d'utiliser discrètement les valeurs par défaut.
fs.existsSync : pourquoi tenter directement la lecture
fs.existsSync(path) renvoie true ou false, et on est tenté de vérifier avant de lire :
if (fs.existsSync('data.txt')) {
const text = fs.readFileSync('data.txt', 'utf8');
}
Cela fait deux étapes là où une suffit, et le fichier peut être supprimé entre les deux, donc la lecture peut quand même échouer. Tentez la lecture et gérez ENOENT, comme ci-dessus. existsSync convient quand vous voulez seulement savoir si quelque chose existe sans l'ouvrir, par exemple pour décider de créer un dossier.
Lire un fichier JSON
Lisez le texte, puis parsez-le avec JSON.parse. Un fichier avec une erreur de syntaxe lève une SyntaxError, donc gardez-le dans le même try.
Le programme affiche 3001 et boolean : après le parsing, les valeurs ont leur type JSON. require('./config.json') fonctionne aussi, mais il met le résultat en cache, donc un second require renvoie l'ancien objet même après une modification du fichier.
Lire un fichier ligne par ligne
Pour un fichier qui tient en mémoire, lisez-le en entier et découpez-le sur le caractère de fin de ligne. Filtrez la chaîne vide qu'un saut de ligne final laisse derrière lui.
Le découpage donne 4 éléments, le dernier vide, donc la boucle affiche trois lignes numérotées. Les fichiers écrits sous Windows terminent leurs lignes par \r\n ; découpez sur /\r?\n/ pour gérer les deux.
Un log de plusieurs gigaoctets ne tient pas en mémoire. Lisez-le en stream, pour ne garder qu'une ligne à la fois :
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();
Erreurs fréquentes
Utiliser le résultat en dehors du callback. const text = fs.readFile(...) vaut undefined. Le contenu n'existe que dans le callback, ou après await.
Oublier l'encodage. Sans 'utf8', vous obtenez un Buffer, et data.split('\n') lève data.split is not a function. Passez l'encodage dès que vous voulez du texte.
Des chemins relatifs au mauvais dossier. 'data.txt' est cherché là où node a été lancé. Utilisez path.join(__dirname, 'data.txt') pour un fichier livré à côté de votre script.
Questions fréquentes
Pourquoi fs.readFile renvoie-t-il undefined ?
fs.readFile ne renvoie pas le contenu. Il lance la lecture et appelle plus tard votre callback avec (err, data). Utilisez les données dans le callback, appelez readFileSync, ou attendez la version à promesses avec await.
Où Node cherche-t-il un chemin relatif comme 'data.txt' ?
Dans le répertoire de travail courant, le dossier depuis lequel vous avez lancé node, pas dans le dossier du script. Pour lire un fichier situé à côté du script, construisez le chemin avec path.join(__dirname, 'data.txt').
fs.readFile peut-il lire un fichier depuis une URL ?
Non, il lit uniquement depuis le système de fichiers. Pour récupérer un fichier en HTTP, utilisez fetch puis await res.text().
Quelle taille de fichier readFile peut-il gérer ?
Il charge tout le fichier en mémoire, donc il convient aux configs, aux templates et aux petits fichiers de données. Pour des fichiers de plusieurs centaines de mégaoctets, lisez-les par morceaux avec fs.createReadStream.