Próbowałem znaleźć sposób na pisanie do pliku podczas korzystania z Node.js, ale bez powodzenia. Jak mogę to zrobić?
Jest wiele szczegółów w File System API. Najczęstszym sposobem jest:
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Obecnie istnieją trzy sposoby zapisu pliku:
fs.write(fd, bufor, offset, length, position, callback
)
Musisz poczekać na callback, aby upewnić się, że bufor został zapisany na dysk. To nie jest buforowane.
fs.writeFile(filename, data, [encoding], callback)
Wszystkie dane muszą być zapisane w tym samym czasie, nie można wykonywać zapisów sekwencyjnych.
fs.createWriteStream(ścieżka, [opcje]
)
Tworzy strumień WriteStream
, co jest wygodne, ponieważ nie trzeba czekać na wywołanie zwrotne. Ale znowu, to'nie jest buforowane.
A WriteStream
, jak sama nazwa mówi, jest strumieniem. Strumień z definicji jest "buforem" zawierającym dane, które poruszają się w jednym kierunku (źródło ► miejsce docelowe). Ale zapisywalny strumień niekoniecznie jest "buforowany". Strumień jest "buforowany", kiedy piszesz n
razy, a w czasie n+1
, strumień wysyła bufor do jądra (ponieważ jest pełny i musi zostać przepłukany).
Innymi słowy: "Bufor" jest obiektem. To, czy "jest buforowany" jest właściwością tego obiektu, czy nie.
Jeśli spojrzysz na kod, WriteStream
dziedziczy po zapisywalnym obiekcie Stream
. Jeśli zwrócisz uwagę, zobaczysz jak one spłukują zawartość; nie mają żadnego systemu buforowania.
Jeśli piszesz ciąg znaków, jest on konwertowany do bufora, a następnie wysyłany do warstwy natywnej i zapisywany na dysk. Podczas pisania ciągów, nie wypełniają one żadnego bufora. Więc, jeśli zrobisz:
write("a")
write("b")
write("c")
You're doing:
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
To są trzy wywołania do warstwy I/O. Chociaż używasz "buforów", dane nie są buforowane. Buforowany strumień zrobiłby: fs.write(new Buffer ("abc"))
, jedno wywołanie do warstwy I/O.
Na dzień dzisiejszy w Node.js v0.12 (wersja stabilna ogłoszona 02/06/2015) obsługuje teraz dwie funkcje:
cork()
oraz.
uncork()
. Wygląda na to, że te funkcje w końcu pozwolą ci buforować / spłukiwać wywołania zapisu.
Na przykład, w Javie są pewne klasy, które zapewniają buforowane strumienie (BufferedOutputStream
, BufferedWriter
...). Jeśli napiszesz trzy bajty, będą one przechowywane w buforze (pamięci) zamiast wykonywać wywołanie I/O tylko dla trzech bajtów. Kiedy bufor jest pełny, jego zawartość jest przepłukiwana i zapisywana na dysk. Poprawia to wydajność.
Nie odkrywam niczego, po prostu pamiętam, jak powinien być wykonywany dostęp do dysku.
Możesz oczywiście uczynić go nieco bardziej zaawansowanym. Non-blocking, zapisywanie fragmentów, nie zapisywanie całego pliku na raz:
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();
});