Pisanie plików w Node.js

Próbowałem znaleźć sposób na pisanie do pliku podczas korzystania z Node.js, ale bez powodzenia. Jak mogę to zrobić?

Rozwiązanie

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!");
}); 
Komentarze (16)

Obecnie istnieją trzy sposoby zapisu pliku:

  1. 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.

  2. fs.writeFile(filename, data, [encoding], callback)

    Wszystkie dane muszą być zapisane w tym samym czasie, nie można wykonywać zapisów sekwencyjnych.

  3. 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.

Komentarze (5)

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();
});
Komentarze (9)