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?


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

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.


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

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.");
}

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

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


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


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 )



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

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

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.



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


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.


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

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!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.