Wie überprüfe ich das Vorhandensein einer Datei?
In der Dokumentation zum Modul fs
wird die Methode fs.exists(path, callback)
beschrieben. Aber ich verstehe, dass nur Verzeichnisse vorhanden sind. Und ich muss die file überprüfen!
Wie kann das gemacht werden?
Warum nicht einfach versuchen, die Datei zu öffnen? fs.open('YourFile', 'a', function (err, fd) { ... })
trotzdem nach einer minuziösen Suche versuchen Sie dies:
var path = require('path');
path.exists('foo.txt', function(exists) {
if (exists) {
// do something
}
});
// or
if (path.existsSync('foo.txt')) {
// do something
}
Für Node.js v0.12.x und höher
Sowohl path.exists
als auch fs.exists
sind veraltet
*Bearbeiten:
Geändert: else if(err.code == 'ENOENT')
an: else if(err.code === 'ENOENT')
Linter beklagt sich, dass das Doppelte nicht das Dreifache ist.
Verwendung von fs.stat:
fs.stat('foo.txt', function(err, stat) {
if(err == null) {
console.log('File exists');
} else if(err.code === 'ENOENT') {
// file does not exist
fs.writeFile('log.txt', 'Some log\n');
} else {
console.log('Some other error: ', err.code);
}
});
Ein einfacher Weg, dies synchron zu tun.
if (fs.existsSync('/etc/file')) {
console.log('Found file');
}
Das API-Dokument gibt an, wie existsSync
funktioniert:
Testen Sie anhand des Dateisystems, ob der angegebene Pfad vorhanden ist.
Eine Alternative für stat könnte die Verwendung der neuen fs.access(...)
sein:
verminderte kurze Versprechungsfunktion zur Überprüfung von:
s => new Promise(r=>fs.access(s, fs.F_OK, e => r(!e)))
Verwendungsbeispiel:
let checkFileExists = s => new Promise(r=>fs.access(s, fs.F_OK, e => r(!e)))
checkFileExists("Some File Location")
.then(bool => console.log(´file exists: ${bool}´))
erweiterte Versprechungsweise:
// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
return new Promise((resolve, reject) => {
fs.access(filepath, fs.F_OK, error => {
resolve(!error);
});
});
}
oder wenn du es synchron machen willst:
function checkFileExistsSync(filepath){
let flag = true;
try{
fs.accessSync(filepath, fs.F_OK);
}catch(e){
flag = false;
}
return flag;
}
fs.exists(path, callback)
und fs.existsSync(path)
sind jetzt veraltet, siehe https://nodejs.org/api/fs.html#fs_fs_exists_path_callback und https://nodejs.org/api/fs.html#fs_fs_existssync_path .
Um das Vorhandensein einer Datei synchron zu testen, kann man zB. fs.statSync(path)
. Ein fs.Stats
object wird zurückgegeben, wenn die Datei existiert, siehe https://nodejs.org/api/fs.html#fs_class_fs_stats , andernfalls wird ein Fehler ausgegeben, der von der try/catch-Anweisung abgefangen wird .
var fs = require('fs'),
path = '/path/to/my/file',
stats;
try {
stats = fs.statSync(path);
console.log("File exists.");
}
catch (e) {
console.log("File does not exist.");
}
Alte Version vor V6: hier ist die Dokumentation
const fs = require('fs');
fs.exists('/etc/passwd', (exists) => {
console.log(exists ? 'it\'s there' : 'no passwd!');
});
// or Sync
if (fs.existsSync('/etc/passwd')) {
console.log('it\'s there');
}
UPDATE
Neue Versionen von V6: Dokumentation für fs.stat
fs.stat('/etc/passwd', function(err, stat) {
if(err == null) {
//Exist
} else if(err.code == 'ENOENT') {
// NO exist
}
});
fs.exists
ist seit 1.0.0 veraltet. Sie können stattdessen fs.stat
verwenden.
var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this
}
else { // do this
}});
Hier ist der Link zur Dokumentation fs.stats
@Fox: großartige Antwort! Hier ist eine Erweiterung mit einigen weiteren Optionen. Das habe ich in letzter Zeit als Go-To-Lösung verwendet:
var fs = require('fs');
fs.lstat( targetPath, function (err, inodeStatus) {
if (err) {
// file does not exist-
if (err.code === 'ENOENT' ) {
console.log('No file or directory at',targetPath);
return;
}
// miscellaneous error (e.g. permissions)
console.error(err);
return;
}
// Check if this is a file or directory
var isDirectory = inodeStatus.isDirectory();
// Get file size
//
// NOTE: this won't work recursively for directories-- see:
// http://stackoverflow.com/a/7550430/486547
//
var sizeInBytes = inodeStatus.size;
console.log(
(isDirectory ? 'Folder' : 'File'),
'at',targetPath,
'is',sizeInBytes,'bytes.'
);
}
P.S. Schauen Sie sich fs-extra an, wenn Sie es nicht bereits verwenden - es ist ziemlich süß . https://github.com/jprichardson/node-fs-extra )
Es gibt viele ungenaue Kommentare zu fs.existsSync()
, die veraltet sind. es ist nicht.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
Beachten Sie, dass fs.exists () veraltet ist, fs.existsSync () jedoch nicht.
fs.statSync(path, function(err, stat){
if(err == null) {
console.log('File exists');
//code when all ok
}else if (err.code == "ENOENT") {
//file doesn't exist
console.log('not file');
}
else {
console.log('Some other error: ', err.code);
}
});
Nach ein wenig Experimentieren fand ich das folgende Beispiel mit fs.stat
eine gute Möglichkeit, um asynchron zu prüfen, ob eine Datei existiert. Es wird auch überprüft, ob Ihre "Datei" "wirklich-is-a-Datei" ist (und kein Verzeichnis).
Diese Methode verwendet Promises, vorausgesetzt, Sie arbeiten mit einer asynchronen Codebasis:
const fileExists = path => {
return new Promise((resolve, reject) => {
try {
fs.stat(path, (error, file) => {
if (!error && file.isFile()) {
return resolve(true);
}
if (error && error.code === 'ENOENT') {
return resolve(false);
}
});
} catch (err) {
reject(err);
}
});
};
Wenn die Datei nicht vorhanden ist, wird das Versprechen immer noch aufgelöst, jedoch false
. Wenn die Datei existiert und es sich um ein Verzeichnis handelt, wird true
aufgelöst. Alle Fehler beim Versuch, die Datei zu lesen, reject
versprechen den Fehler selbst.
Nun, ich habe es so gemacht, wie auf https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback zu sehen ist.
fs.access('./settings', fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err){
console.log(err ? 'no access or dir doesnt exist' : 'R/W ok');
if(err && err.code === 'ENOENT'){
fs.mkdir('settings');
}
});
Gibt es ein Problem damit?
async/await
Version mit util.promisify
ab Knoten 8:
const fs = require('fs');
const { promisify } = require('util');
const stat = promisify(fs.stat);
describe('async stat', () => {
it('should not throw if file does exist', async () => {
try {
const stats = await stat(path.join('path', 'to', 'existingfile.txt'));
assert.notEqual(stats, null);
} catch (err) {
// shouldn't happen
}
});
});
describe('async stat', () => {
it('should throw if file does not exist', async () => {
try {
const stats = await stat(path.join('path', 'to', 'not', 'existingfile.txt'));
} catch (err) {
assert.notEqual(err, null);
}
});
});
function fileExists(path, cb){
return fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result)) //F_OK checks if file is visible, is default does no need to be specified.
}
die docs Sie sollten access()
als Ersatz für veraltete exists()
verwenden.
function fileExists(path, cb){
return new Promise((accept,deny) =>
fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
);
}
var fs = require('fs-extra')
await fs.pathExists(filepath)
Da sieht man viel einfacher. Und der Vorteil gegenüber Promisify ist, dass Sie mit diesem Paket vollständige Typisierungen haben (Complete Intellisense/TypeScript)! In den meisten Fällen haben Sie diese Bibliothek bereits integriert, da andere Bibliotheken (+ -10.000) davon abhängig sind.
Modern async/await way (Node 12.8.x)
const fileExists = async path => !!(await fs.promises.stat(path).catch(e => false));
console.log(await fileExists('/path/myfile.txt'));
Mit fs.stat
können Sie prüfen, ob das Ziel eine Datei oder ein Verzeichnis ist. Mit fs.access
können Sie prüfen, ob Sie die Datei schreiben, lesen oder ausführen können. (Denken Sie daran, path.resolve
zu verwenden, um den vollständigen Pfad für das Ziel zu erhalten.)
Dokumentation:
Vollständiges Beispiel (TypeScript)
import * as fs from 'fs';
import * as path from 'path';
const targetPath = path.resolve(process.argv[2]);
function statExists(checkPath): Promise<fs.Stats> {
return new Promise((resolve) => {
fs.stat(checkPath, (err, result) => {
if (err) {
return resolve(undefined);
}
return resolve(result);
});
});
}
function checkAccess(checkPath: string, mode: number = fs.constants.F_OK): Promise<boolean> {
return new Promise((resolve) => {
fs.access(checkPath, mode, (err) => {
resolve(!err);
});
});
}
(async function () {
const result = await statExists(targetPath);
const accessResult = await checkAccess(targetPath, fs.constants.F_OK);
const readResult = await checkAccess(targetPath, fs.constants.R_OK);
const writeResult = await checkAccess(targetPath, fs.constants.W_OK);
const executeResult = await checkAccess(targetPath, fs.constants.X_OK);
const allAccessResult = await checkAccess(targetPath, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);
if (result) {
console.group('stat');
console.log('isFile: ', result.isFile());
console.log('isDir: ', result.isDirectory());
console.groupEnd();
}
else {
console.log('file/dir does not exist');
}
console.group('access');
console.log('access:', accessResult);
console.log('read access:', readResult);
console.log('write access:', writeResult);
console.log('execute access:', executeResult);
console.log('all (combined) access:', allAccessResult);
console.groupEnd();
process.exit(0);
}());
in alten Tagen, bevor ich mich hinsetze, prüfe ich immer, ob der Stuhl da ist, dann sitze ich, sonst habe ich einen alternativen Plan wie einen Trainer. Nun schlägt node.js vor, einfach zu gehen (keine Notwendigkeit zu überprüfen) und die Antwort sieht folgendermaßen aus:
fs.readFile( '/foo.txt', function( err, data )
{
if(err)
{
if( err.code === 'ENOENT' )
{
console.log( 'File Doesn\'t Exist' );
return;
}
if( err.code === 'EACCES' )
{
console.log( 'No Permission' );
return;
}
console.log( 'Unknown Error' );
return;
}
console.log( data );
} );
code entnommen aus http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ ab März 2014 und geringfügig an den Computer angepasst. Es wird auch auf Erlaubnis geprüft - Erlaubnis zum Testen von chmod a-r foo.txt
entfernt