Node.js prüft, ob eine Datei vorhanden ist

143

Wie überprüfe ich das Vorhandensein einer Datei ?

In der Dokumentation zum Modul fsfinden Sie eine Beschreibung der Methode fs.exists(path, callback). Soweit ich weiß, wird jedoch nur nach Verzeichnissen gesucht. Und ich muss die Datei überprüfen !

Wie kann das gemacht werden?

RomanGorbatko
quelle
3
Ab 2018 Verwendung fs.access('file', err => err ? 'does not exist' : 'exists')finden fs.access
MB21

Antworten:

227

Warum nicht einfach versuchen, die Datei zu öffnen? fs.open('YourFile', 'a', function (err, fd) { ... }) Trotzdem versuchen Sie nach einer Minute Suche Folgendes:

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

Beide path.existsund fs.existssind veraltet

*Bearbeiten:

Geändert: else if(err.code == 'ENOENT')

zu: else if(err.code === 'ENOENT')

Linter beschwert sich darüber, dass die Doppelgleichheit nicht die Dreifachgleichheit ist.

Verwenden 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);
    }
});
dardar.moh
quelle
1
Aber wie sich herausstellte, fs.existsfunktioniert es auch. Ich hatte Probleme mit den Berechtigungen für die Datei.
RomanGorbatko
11
path.existstatsächlich ist zugunsten vonfs.exists
Arnaud Rinquin
42
Jeder, der dies jetzt liest (Node.js v0.12.x), denkt daran fs.existsund fs.existsSyncist ebenfalls veraltet. Der beste Weg, um das Vorhandensein von Dateien zu überprüfen, ist fs.stat, wie oben gezeigt.
Antrikshy
8
Aus der Dokumentation von Node js geht hervor, dass der beste Weg, wenn Sie die Datei nach Überprüfung ihrer Existenz öffnen möchten, darin besteht, sie tatsächlich zu öffnen und die Fehler zu behandeln, wenn sie nicht vorhanden sind. Weil Ihre Datei zwischen Ihrer vorhandenen Prüfung und der
Öffnungsfunktion
6
@Antrikshy fs.existsSyncist nicht mehr beraubt, obwohl es fs.existsimmer noch ist.
RyanZim
52

Ein einfacher Weg, dies synchron zu tun.

if (fs.existsSync('/etc/file')) {
    console.log('Found file');
}

Das API-Dokument beschreibt, wie es existsSyncfunktioniert:
Testen Sie, ob der angegebene Pfad vorhanden ist, indem Sie mit dem Dateisystem prüfen.

Paul Ho
quelle
12
fs.existsSync(path)ist jetzt veraltet, siehe nodejs.org/api/fs.html#fs_fs_existssync_path . Eine synchrone Implementierung fs.statSync(path)wird empfohlen, siehe meine Antwort.
lmeurs
20
@Imeurs aber nodejs.org/api/fs.html#fs_fs_existssync_path sagen: Beachten Sie, dass fs.exists () veraltet ist, fs.existsSync () jedoch nicht.
HaveF
9
fs.existsSyncwurde veraltet, ist es aber nicht mehr.
RyanZim
44

Bearbeiten: Seit Knoten v10.0.0könnten wir verwendenfs.promises.access(...)

Beispiel für einen asynchronen Code, der prüft, ob eine Datei vorhanden ist:

async function checkFileExists(file) {
  return fs.promises.access(file, fs.constants.F_OK)
           .then(() => true)
           .catch(() => false)
}

Eine Alternative für stat könnte die Verwendung des neuen sein fs.access(...) :

minimierte Kurzversprechungsfunktion zur Überprüfung:

s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))

Beispielnutzung:

let checkFileExists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
checkFileExists("Some File Location")
  .then(bool => console.logfile exists: ${bool}´))

erweiterter Versprechen Weg:

// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
  return new Promise((resolve, reject) => {
    fs.access(filepath, fs.constants.F_OK, error => {
      resolve(!error);
    });
  });
}

oder wenn du es synchron machen willst:

function checkFileExistsSync(filepath){
  let flag = true;
  try{
    fs.accessSync(filepath, fs.constants.F_OK);
  }catch(e){
    flag = false;
  }
  return flag;
}
mido
quelle
1
Upvoted, dies ist definitiv die modernste (2018) Methode, um festzustellen, ob eine Datei in Node.js
AKMorris
1
Ja, dies ist die offiziell empfohlene Methode, um einfach zu überprüfen, ob die Datei vorhanden ist, und eine anschließende Manipulation wird nicht erwartet. Verwenden Sie andernfalls open / write / read und behandeln Sie den Fehler. nodejs.org/api/fs.html#fs_fs_stat_path_callback
Justin
1
In der Dokumentation finde ich fs.constants.F_OKetc. Ist es auch möglich wie darauf zuzugreifen fs.F_OK? Seltsam. Auch knapp, was schön ist.
Samson
1
Könnte versuchen, es fs.promises.access(path, fs.constants.F_OK);einfach zu einem Versprechen zu machen, anstatt ein Versprechen zu erstellen.
Jeremy Trpka
18

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 die Existenz einer Datei synchron zu testen, kann man dh verwenden. fs.statSync(path). Ein fs.StatsObjekt wird zurückgegeben, wenn die Datei vorhanden ist (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.");
}
lmeurs
quelle
10
Der Link, den Sie für fs.existsync angegeben haben, zeigt eindeutig an, dass er NICHT veraltet ist. "Beachten Sie, dass fs.exists () veraltet ist, fs.existsSync () jedoch nicht. (Der Rückrufparameter für fs.exists () akzeptiert Parameter, die inkonsistent sind mit anderen Node.js Rückrufen. fs.existsSync () verwendet keinen Rückruf.) "
Shreddish
die erste (von oben) Antwort, die erwähnte, woher die fsVariable kommt
Dmitry Korolyov
Zum Zeitpunkt der Erstellung dieser Antwort waren die Informationen korrekt. ist jedoch fs.existsSync()nicht mehr veraltet.
RyanZim
12

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');
  }

AKTUALISIEREN

Neue Versionen von V6: Dokumentation fürfs.stat

fs.stat('/etc/passwd', function(err, stat) {
    if(err == null) {
        //Exist
    } else if(err.code == 'ENOENT') {
        // NO exist
    } 
});
Ignacio Hernández
quelle
1
Beide fs.existsund fs.existsSyncsind gemäß dem von Ihnen freigegebenen Link veraltet.
Andy
existsSyncist gemäß diesem Dokument nicht veraltet, möglicherweise war es, als Sie es gelesen haben.
Darpan
11

Moderner asynchroner / wartender Weg (Knoten 12.8.x)

const fileExists = async path => !!(await fs.promises.stat(path).catch(e => false));

const main = async () => {
    console.log(await fileExists('/path/myfile.txt'));
}

main();

Wir müssen verwenden, fs.stat() or fs.access()weil fs.exists(path, callback)jetzt veraltet ist

Ein weiterer guter Weg ist fs-extra

Дмитрий Васильев
quelle
7

fs.existsist seit 1.0.0 veraltet. Sie können fs.statstattdessen 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

Koushik Das
quelle
stats.isFile()braucht nicht filename.
Wtower
6

@ Fox: tolle Antwort! Hier ist eine kleine Erweiterung mit einigen weiteren Optionen. Es ist das, was ich in letzter Zeit als Lösung verwendet habe:

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.'
  );


}

PS: Schauen Sie sich fs-extra an, wenn Sie es noch nicht verwenden - es ist ziemlich süß. https://github.com/jprichardson/node-fs-extra )

mikermcneil
quelle
3

async/awaitVersion mit util.promisifyab 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);
    }
  });
});
Alexander Zeitler
quelle
2
  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);
      }
    });
D.Belda
quelle
2

Nach einigem Experimentieren fand ich das folgende Beispiel fs.statals eine gute Möglichkeit, asynchron zu überprüfen, ob eine Datei vorhanden ist. Es wird auch überprüft, ob Ihre "Datei" "wirklich eine Datei" ist (und kein Verzeichnis).

Diese Methode verwendet Versprechen, 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 dennoch aufgelöst false. Wenn die Datei vorhanden ist und es sich um ein Verzeichnis handelt, wird sie aufgelöst true. Alle Fehler, die versuchen, die Datei zu lesen, rejectversprechen den Fehler selbst.

f1lt3r
quelle
0

In alten Zeiten, bevor ich mich hinsetze, überprüfe ich immer, ob ein Stuhl da ist, dann sitze ich, sonst habe ich einen alternativen Plan wie in einem Bus sitzen. Jetzt schlagen die Website node.js vor, einfach loszulegen (keine Überprüfung erforderlich), 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 von http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ aus dem März 2014 entnommen und leicht an den Computer angepasst. Es wird auch nach Berechtigungen gesucht - entfernen Sie die Berechtigung zum Testenchmod a-r foo.txt

user2167003
quelle
0

Rückruf von vannilla Nodejs

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 Dokumente sagen, dass Sie access()als Ersatz für veraltete verwenden solltenexists()

Knoten mit eingebautem Versprechen (Knoten 7+)

function fileExists(path, cb){
  return new Promise((accept,deny) => 
    fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
  );
}

Beliebtes Javascript-Framework

fs-extra

var fs = require('fs-extra')
await fs.pathExists(filepath)

Wie Sie viel einfacher sehen. Und der Vorteil gegenüber Promisify ist, dass Sie mit diesem Paket vollständige Schreibvorgänge haben (vollständiges Intellisense / Typoskript)! In den meisten Fällen haben Sie diese Bibliothek bereits aufgenommen, da (+ -10.000) andere Bibliotheken davon abhängen.

Joel Harkes
quelle
0

Sie können verwenden fs.stat, um zu überprüfen, ob das Ziel eine Datei oder ein Verzeichnis ist, und um fs.accesszu überprüfen, ob Sie die Datei schreiben / lesen / ausführen können. (Denken Sie daran, zu verwendenpath.resolve , den vollständigen Pfad für das Ziel zu verwenden.)

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);
}());
BrunoLM
quelle
0

Für asynchrone Version! Und mit der Versprechensversion! Hier der saubere einfache Weg!

try {
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    // do something
} catch (err) {
    if (err.code = 'ENOENT') {
        /**
        * File not found
        */
    } else {
        // Another error!
    }
}

Ein praktischerer Ausschnitt aus meinem Code zur besseren Veranschaulichung:


try {
    const filePath = path.join(FILES_DIR, fileName);
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    const readStream = fs.createReadStream(
        filePath,
        {
            autoClose: true,
            start: 0
        }
    );

    return {
        success: true,
        readStream
    };
} catch (err) {
    /**
     * Mapped file doesn't exists
     */
    if (err.code = 'ENOENT') {
        return {
            err: {
                msg: 'Mapped file doesn\'t exists',
                code: EErrorCode.MappedFileNotFound
            }
        };
    } else {
        return {
            err: {
                msg: 'Mapped file failed to load! File system error',
                code: EErrorCode.MappedFileFileSystemError
            }
        }; 
   }
}

Das obige Beispiel dient nur zur Demonstration! Ich hätte das Fehlerereignis des Lesestreams verwenden können! Fehler abfangen! Und überspringen Sie die beiden Anrufe!

Mohamed Allal
quelle