J’ai essayé de trouver un moyen d’écrire dans un fichier en utilisant Node.js, mais sans succès. Comment puis-je le faire ?
Il existe de nombreux détails dans l'[API du système de fichiers][1]. La méthode la plus courante est la suivante :
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Actuellement, il existe trois façons d'écrire un fichier :
[fs.write(fd, buffer, offset, length, position, callback
)][1]
Vous devez attendre le callback pour vous assurer que le tampon est écrit sur le disque. Il n'est pas mis en mémoire tampon.
[fs.writeFile(nom du fichier, données, [encodage], callback)
][2]
Toutes les données doivent être stockées en même temps ; vous ne pouvez pas effectuer d'écritures séquentielles.
[fs.createWriteStream(path, [options]
)][3]
Crée un [WriteStream
][4], ce qui est pratique car vous n'avez pas besoin d'attendre un callback. Mais là encore, il n'y a pas de mise en mémoire tampon.
Un [WriteStream
][4], comme son nom l'indique, est un flux. Par définition, un flux est "un tampon" contenant des données qui se déplacent dans une seule direction (source ► destination). Mais un flux inscriptible n'est pas nécessairement "tamponné". Un flux est "tamponné" lorsque vous écrivez n
fois, et qu'au temps n+1
, le flux envoie le tampon au noyau (parce qu'il est plein et qu'il faut le vider).
En d'autres termes: "Un tampon" est l'objet. Le fait qu'il soit "tamponné" ou non est une propriété de cet objet.
Si vous regardez le code, le WriteStream
hérite d'un objet Stream
inscriptible. Si vous prêtez attention, vous verrez comment ils vident le contenu ; ils n'ont pas de système de mise en mémoire tampon.
Si vous écrivez une chaîne, elle est convertie en tampon, puis envoyée à la couche native et écrite sur le disque. Lorsque vous écrivez des chaînes de caractères, elles ne remplissent pas de tampon. Donc, si vous le faites :
write("a")
write("b")
write("c")
C'est ce que vous faites :
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
C'est trois appels à la couche E/S. Bien que vous utilisiez des "buffers", les données ne sont pas mises en mémoire tampon. Un flux mis en mémoire tampon suffirait : fs.write(new Buffer ("abc"))
, un seul appel à la couche E/S.
A partir de maintenant, dans Node.js v0.12 (version stable annoncée le 02/06/2015) supporte maintenant deux fonctions :
cork()
et
uncork()
. Il semble que ces fonctions permettent enfin de buffer/flush les appels d'écriture.
Par exemple, en Java, il existe des classes qui fournissent des flux tamponnés (BufferedOutputStream
, BufferedWriter
...). Si vous écrivez trois octets, ces octets seront stockés dans le tampon (mémoire) au lieu de faire un appel E/S juste pour trois octets. Lorsque le tampon est plein, le contenu est purgé et enregistré sur le disque. Cela améliore les performances.
Je ne découvre rien, je me rappelle simplement comment un accès au disque devrait être effectué.
[1] : http://nodejs.org/api/fs.html#fs_fs_write_fd_buffer_offset_length_position_callback [2] : http://nodejs.org/api/fs.html#fs_fs_writefile_filename_data_options_callback [3] : http://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options [4] : https://github.com/joyent/node/blob/master/lib/fs.js#L1623
Vous pouvez bien sûr le rendre un peu plus avancé. Non-blocage, écriture de morceaux, pas d'écriture de tout le fichier en une seule fois :
var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
stream.write("My first row\n");
stream.write("My second row\n");
stream.end();
});