Majstrowałem przy Node.js i znalazłem mały problem. Mam skrypt, który znajduje się w katalogu o nazwie data
. Chcę, aby skrypt zapisywał dane do pliku w podkatalogu w tym data
podkatalogu. Jednak pojawia się następujący błąd:
{ [Error: ENOENT, open 'D:\data\tmp\test.txt'] errno: 34, code: 'ENOENT', path: 'D:\\data\\tmp\\test.txt' }
Kod wygląda następująco:
var fs = require('fs');
fs.writeFile("tmp/test.txt", "Hey there!", function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
Czy ktoś może mi pomóc w znalezieniu sposobu, aby Node.js utworzył strukturę katalogów, jeśli nie kończy się ona w celu zapisania do pliku?
javascript
node.js
Hirvesh
źródło
źródło
fs.promises.mkdir(path.dirname("tmp/test.txt"), {recursive: true}).then(x => fs.promises.writeFile("tmp/test.txt", "Hey there!"))
Odpowiedzi:
Węzeł> 10.12.0
fs.mkdir akceptuje teraz taką
{ recursive: true }
opcję:// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist. fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => { if (err) throw err; });
lub z obietnicą:
fs.promises.mkdir('/tmp/a/apple', { recursive: true }).catch(console.error);
Węzeł <= 10.11.0
Możesz rozwiązać ten problem za pomocą pakietu takiego jak mkdirp lub fs-extra . Jeśli nie chcesz instalować pakietu, zapoznaj się z odpowiedzią Tiago Peres França poniżej.
źródło
fs.promises
jest to nadal eksperymentalny nodejs.org/dist/latest-v10.x/docs/api/ ...Jeśli nie chcesz używać żadnego dodatkowego pakietu, możesz wywołać następującą funkcję przed utworzeniem pliku:
var path = require('path'), fs = require('fs'); function ensureDirectoryExistence(filePath) { var dirname = path.dirname(filePath); if (fs.existsSync(dirname)) { return true; } ensureDirectoryExistence(dirname); fs.mkdirSync(dirname); }
źródło
statSync
zamiastexistsSync
, w oparciu o stackoverflow.com/questions/4482686/ ...path
to także pakiet, który musi być wymagany tak jakfs
:var path = require('path')
na wypadek, gdyby ktoś się zastanawiał. Zobacz dokumentację węzła .fs.existsSync
nie jest przestarzała , tylkofs.exists
jest.Dzięki node-fs-extra możesz to łatwo zrobić.
Zainstaluj to
Następnie użyj
outputFile
metody. Jego dokumentacja mówi:Możesz go używać na trzy sposoby:
Styl oddzwaniania
const fse = require('fs-extra'); fse.outputFile('tmp/test.txt', 'Hey there!', err => { if(err) { console.log(err); } else { console.log('The file was saved!'); } })
Korzystanie z obietnic
Jeśli korzystasz z obietnic i mam nadzieję, że tak, to jest kod:
fse.outputFile('tmp/test.txt', 'Hey there!') .then(() => { console.log('The file was saved!'); }) .catch(err => { console.error(err) });
Wersja synchronizacji
Jeśli chcesz wersję do synchronizacji, użyj tego kodu:
fse.outputFileSync('tmp/test.txt', 'Hey there!')
Aby uzyskać pełne informacje, zapoznaj się z
outputFile
dokumentacją i wszystkimi obsługiwanymi metodami node-fs-extra .źródło
Bezwstydny alarm wtyczki!
Będziesz musiał sprawdzić każdy katalog w wybranej strukturze ścieżek i utworzyć go ręcznie, jeśli nie istnieje. Wszystkie narzędzia do tego są już dostępne w module fs Node, ale możesz to zrobić po prostu za pomocą mojego modułu mkpath: https://github.com/jrajav/mkpath
źródło
Ponieważ nie mogę jeszcze komentować, zamieszczam ulepszoną odpowiedź opartą na fantastycznym rozwiązaniu @ tiago-peres-frança (dzięki!). Jego kod nie tworzy katalogu w przypadku, gdy w ścieżce brakuje tylko ostatniego katalogu, np. Wejście to „C: / test / abc”, a „C: / test” już istnieje. Oto fragment, który działa:
function mkdirp(filepath) { var dirname = path.dirname(filepath); if (!fs.existsSync(dirname)) { mkdirp(dirname); } fs.mkdirSync(filepath); }
źródło
abc
jest interpretowany jako plik, dla którego musisz utworzyć katalog. Aby również utworzyćabc
katalog, dodaj do ścieżki przykładowy plik, npC:/test/abc/dummy.txt
.fs.promises.mkdir(path.dirname(file), {recursive: true}).then(x => fs.promises.writeFile(file, data))
Moja rada brzmi: staraj się nie polegać na zależnościach, kiedy możesz to łatwo zrobić za pomocą kilku linijek kodu
Oto, co próbujesz osiągnąć w 14 wierszach kodu:
fs.isDir = function(dpath) { try { return fs.lstatSync(dpath).isDirectory(); } catch(e) { return false; } }; fs.mkdirp = function(dirname) { dirname = path.normalize(dirname).split(path.sep); dirname.forEach((sdir,index)=>{ var pathInQuestion = dirname.slice(0,index+1).join(path.sep); if((!fs.isDir(pathInQuestion)) && pathInQuestion) fs.mkdirSync(pathInQuestion); }); };
źródło
return fs.lstatSync(dpath).isDirectory()
, w przeciwnym razie co by się stało, gdyby isDirectory () zwróciło false?fs.promises.mkdir(path.dirname(file), {recursive: true}).then(x => fs.promises.writeFile(file, data))
Właśnie opublikowałem ten moduł, ponieważ potrzebowałem tej funkcjonalności.
https://www.npmjs.org/package/filendir
Działa jak wrapper wokół metod Node.js fs. Możesz więc używać go dokładnie w taki sam sposób, jak z
fs.writeFile
ifs.writeFileSync
(zarówno asynchroniczne, jak i synchroniczne zapisy)źródło
najpierw pobiera pełną ścieżkę łącznie z katalogiem i rozpakowuje katalog
//Just for the sake of example cwd=process.cwd() filendir=path.resolve(cwd,'_site/assets/text','node.txt') // Extracting directory name mkdir=path.dirname(filendir)
Teraz utwórz katalog, dodaj opcję rekurencyjną: true, jak stwierdził @David Weldon
fs.mkdirSync(mkdir,{recursive:true})
Następnie utwórz plik
data='Some random text' fs.writeFileSync(filendir,data)
źródło