Bandžiau rasti būdą, kaip rašyti į failą naudojant Node.js, bet nesėkmingai. Kaip tai padaryti?
Failų sistemos API pateikiama daug informacijos. Dažniausiai pasitaikantis būdas yra:
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Šiuo metu yra trys būdai, kaip įrašyti failą:
fs.write(fd, buferis, poslinkis, ilgis, pozicija, atgalinis skambutis
)
Reikia laukti grįžtamojo ryšio, kad buferis būtų įrašytas į diską. Tai nėra buferis.
fs.writeFile(filename, data, [encoding], callback)
Visi duomenys turi būti įrašomi vienu metu; negalima atlikti nuoseklaus įrašymo.
fs.createWriteStream(kelias, [parinktys]
)
Sukuriamas `WriteStream
, tai patogu, nes nereikia laukti grįžtamojo skambučio. Tačiau vėlgi, jis nėra buferinis.
WriteStream
, kaip sako pavadinimas, yra srautas. Pagal apibrėžimą srautas yra "buferis", kuriame yra duomenų, judančių viena kryptimi (šaltinis ► paskirties vieta). Tačiau rašomas srautas nebūtinai yra "buferinis". Srautas yra "buferinis", kai rašote n
kartų, o n+1
metu srautas siunčia buferį branduoliui (nes jis yra pilnas ir jį reikia išplauti).
Kitaip tariant: "Buferis" yra objektas. Tai, ar jis "yra buferis", ar ne, yra to objekto savybė.
Jei pažiūrėsite į kodą, WriteStream
paveldi iš įrašomo objekto Stream
. Jei atkreipsite dėmesį, pamatysite, kaip jie išplauna turinį; jie neturi jokios buferizavimo sistemos.
Jei rašote eilutę, ji konvertuojama į buferį, tada siunčiama į gimtąjį sluoksnį ir įrašoma į diską. Rašant eilutes, jos' neužpildo jokio buferio. Taigi, jei darote:
write("a")
write("b")
write("c")
Jūs'darote:
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
Tai trys I/O sluoksnio iškvietimai. Nors naudojate "buferius", duomenys nėra buferizuojami. Buferinis srautas būtų toks: fs.write(new Buffer ("abc"))
, vienas I/O sluoksnio iškvietimas.
Nuo šiol Node.js v0.12 (paskelbta stabili versija 02/06/2015) dabar palaiko dvi funkcijas:
(http://nodejs.org/docs/v0.11.5/api/stream.html#stream_writable_cork) ir [`cork()
] (http://nodejs.org/docs/v0.11.5/api/stream.html#stream_writable_cork).
[uncork()
] (http://nodejs.org/docs/v0.11.5/api/stream.html#stream_writable_uncork). Atrodo, kad šios funkcijos pagaliau leis buferizuoti / išplauti rašymo iškvietimus.
Pavyzdžiui, Java kalboje yra keletas klasių, kurios užtikrina buferinius srautus (BufferedOutputStream
, BufferedWriter
...). Jei įrašysite tris baitus, šie baitai bus saugomi buferyje (atmintyje), užuot atlikus I/O iškvietimą tik trims baitams. Kai buferis užsipildo, turinys išplaunamas ir išsaugomas diske. Tai pagerina našumą.
Nieko neatradau, tik prisiminiau, kaip turėtų būti atliekama prieiga prie disko.
Be abejo, galite jį šiek tiek patobulinti. Neblokuoti, rašyti dalimis, o ne visą failą iš karto:
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();
});