Опитвам се да намеря начин да записвам във файл, когато използвам Node.js, но без успех. Как мога да направя това?
В API на файловата система има много подробности. Най-разпространеният начин е:
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
В момента има три начина за запис на файл:
fs.write(fd, buffer, offset, length, position, callback
)
Трябва да изчакате обратното повикване, за да се уверите, че буферът е записан на диска. Той не е буфериран.
fs.writeFile(име на файл, данни, [кодиране], обратна връзка)
Всички данни трябва да се съхраняват едновременно; не можете да извършвате последователни записи.
fs.createWriteStream(path, [options]
)
Създава WriteStream
, което е удобно, защото не е необходимо да чакате обратна връзка. Но отново, той не е буфериран.
WriteStream
, както казва името, е поток. Потокът по дефиниция е "буфер", съдържащ данни, които се движат в една посока (източник ► дестинация). Но не е задължително записващият поток да е "буфериран". Потокът е "буфериран", когато записвате n
пъти, а в момента n+1
потокът изпраща буфера на ядрото (защото е пълен и трябва да се промие).
С други думи: "Буферът" е обектът. Дали той "е буфериран" или не, е свойство на този обект.
Ако погледнете кода, WriteStream
наследява от обект Stream
, който може да се записва. Ако обърнете внимание, ще видите как те промиват съдържанието; те нямат никаква буферна система.
Ако записвате низ, той се преобразува в буфер, след което се изпраща на нативния слой и се записва на диска. Когато пишете низове, те не'запълват никакъв буфер. Така че, ако направите:
write("a")
write("b")
write("c")
Вие'правите:
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
Това са три повиквания към слоя I/O. Въпреки че използвате "буфери", данните не са буферирани. Един буфериран поток би направил следното: fs.write(new Buffer ("abc"))
, едно извикване на входно-изходния слой.
Към момента в Node.js v0.12 (стабилната версия е обявена на 02.06.2015 г.) вече се поддържат две функции:
cork()
и
uncork()
. Изглежда, че тези функции най-накрая ще ви позволят да буферирате/изпразвате повикванията за запис.
Например, в Java има някои класове, които осигуряват буферирани потоци (BufferedOutputStream
, BufferedWriter
...). Ако запишете три байта, тези байтове ще бъдат съхранени в буфера (паметта), вместо да се прави I/O повикване само за три байта. Когато буферът се запълни, съдържанието му се промива и се записва на диска. Това подобрява производителността.
Не'откривам нищо, просто си спомням как трябва да се извършва достъпът до диска.
Разбира се, можете да го направите малко по-усъвършенстван. Без блокиране, записване на части, а не наведнъж на целия файл:
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();
});