Menu

fs.writeFile w Node.js: zapis, dopisywanie, tworzenie plików

Plik w Node.js zapiszesz przez fs.writeFile, fs.writeFileSync albo await writeFile z fs/promises. Jeśli pliku nie ma, zostanie utworzony, a jeśli jest, zostanie zastąpiony; appendFile dopisuje na końcu.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

fs.writeFile(path, data, callback) zapisuje string albo Buffer do pliku. Jeśli plik nie istnieje, Node go tworzy; jeśli istnieje, stara zawartość zostaje zastąpiona. fs.writeFileSync(path, data) robi to samo i czeka, aż zapis się skończy, a fs.appendFile dopisuje na końcu pliku zamiast go zastępować.

Wypisuje saved, a potem tekst odczytany z powrotem; callback dostaje tylko błąd (albo null), nigdy dane. Przekaż 42 zamiast stringa, a wywołanie rzuci TypeError: dane muszą być stringiem albo Bufferem.

writeFile, writeFileSync i fs/promises

Trzy formy przyjmują te same argumenty i różnią się tym, jak czekasz na wynik.

const fs = require('fs');
const fsp = require('fs/promises');

fs.writeFileSync('a.txt', 'one');            // blocks, throws on error

fs.writeFile('b.txt', 'two', (err) => {});   // callback with err

await fsp.writeFile('c.txt', 'three');       // promise, use in async code

Używaj writeFileSync w skryptach i kodzie startowym, a wersji z promise na serwerach, gdzie zapis synchroniczny blokuje każde inne żądanie, dopóki dysk nie skończy. Strona o fs/promises pokazuje resztę API z promise.

Dopisywanie do pliku przez appendFile

writeFile zastępuje cały plik. Żeby dodać linię do logu, użyj appendFile, który za pierwszym razem też tworzy plik.

Pierwszy odczyt wypisuje "second\n", bo drugi writeFileSync zastąpił first, a drugi wypisuje "second\nthird\nfourth\n" (JSON.stringify pokazuje znaki nowej linii). Dodawaj \n sam: żadna z tych funkcji tego nie robi.

writeFileappendFile
Pliku nie maTworzy goTworzy go
Plik istniejeZastępuje zawartośćDopisuje na końcu
Domyślna flaga'w''a'
Typowe użycieZapis całego dokumentu albo JSONLogi, linia po linii

Bez nadpisywania: opcja flag

Trzeci argument może być obiektem opcji. Jego flag decyduje, co dzieje się z istniejącym plikiem. 'wx' znaczy "zapisz, ale zgłoś błąd, jeśli plik już istnieje", czyli bezpieczny sposób na utworzenie pliku tylko raz.

Drugie wywołanie kończy się błędem EEXIST, więc plik nadal zawiera abc123. Zmień nazwę pliku w drugim wywołaniu na id2.txt, a oba wywołania wypiszą created.

Flagi, które spotkasz najczęściej: 'w' (domyślna, zastąp), 'a' (dopisz), 'wx' (tylko utwórz) i 'ax' (dopisz, ale tylko do nowego pliku).

Sprawdzenie najpierw przez fs.existsSync, a potem zapis ma lukę: inny proces może utworzyć plik między sprawdzeniem a zapisem. 'wx' robi oba kroki naraz.

Zapis JSON do pliku

writeFile nie przyjmuje obiektów. Zamień je na tekst przez JSON.stringify; trzeci argument, 2, dodaje wcięcia, żeby plik był czytelny.

Plik zawiera obiekt w kilku wciętych liniach, a ponowne sparsowanie daje równy obiekt, więc ostatnia linia wypisuje 2. Przekaż obiekt bez JSON.stringify, a wywołanie rzuci TypeError.

Najpierw utwórz folder przez mkdir

writeFile tworzy pliki, nie foldery. Zapis do reports/2026/june.txt, gdy reports nie istnieje, kończy się błędem ENOENT. Najpierw utwórz ścieżkę przez mkdir z { recursive: true }, które tworzy każdy brakujący folder i nic nie robi, jeśli już istnieją.

Pierwszy zapis kończy się błędem ENOENT; po mkdir ten sam zapis się udaje, a readdir wypisuje [ 'june.txt' ]. W prawdziwym kodzie buduj takie ścieżki przez path.join, żeby działały też w Windows.

Częste błędy

Zakładanie, że plik jest zapisany zaraz po wywołaniu. fs.writeFile wraca, zanim dane trafią na dysk. Czytaj plik albo zaczynaj następny krok w callbacku, albo poczekaj przez await na wersję z promise.

Utrata danych przez zapis w pętli. Wywołanie writeFile raz na element za każdym razem zastępuje plik, więc zostaje tylko ostatni element. Użyj appendFile albo zbuduj cały string i zapisz go raz.

Zapisywanie [object Object]. Obiekt przepuszczony przez String() albo template literal zapisuje się jako [object Object]. Użyj JSON.stringify.

Najczęściej zadawane pytania

Czy fs.writeFile nadpisuje plik?

Tak. Z domyślną flagą 'w' czyści plik i zapisuje nowe dane, więc stara zawartość znika. Przekaż { flag: 'a' } albo użyj appendFile, żeby zamiast tego dopisywać na końcu.

Czy fs.writeFile tworzy plik, jeśli nie istnieje?

Tak, tworzy plik. Nie tworzy jednak brakujących folderów: zapis do logs/app.log, gdy logs nie istnieje, kończy się błędem ENOENT.

Co mogę przekazać jako dane?

String, Buffer albo tablicę typowaną. Wszystko inne, np. obiekt albo liczba, rzuca TypeError, więc obiekty najpierw zamieniaj przez JSON.stringify, a liczby przez String().

Czy można wiele razy naraz wywołać writeFile na tym samym pliku?

Nie. Dwa równoległe wywołania writeFile na jednym pliku mogą się przeplatać i zostawić wymieszaną zawartość. Poczekaj, aż jedno się skończy, zanim zaczniesz następne, albo zbierz dane i zapisz raz.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

Zacznij