Node.js memeriksa apakah ada file


143

Bagaimana saya memeriksa keberadaan file ?

Dalam dokumentasi untuk modul tersebut fsada deskripsi metode fs.exists(path, callback). Tapi, seperti yang saya mengerti, ini memeriksa keberadaan hanya direktori. Dan saya perlu memeriksa file !

Bagaimana ini bisa dilakukan?


3
Pada 2018, gunakan fs.access('file', err => err ? 'does not exist' : 'exists'), lihat fs.access
mb21

Jawaban:


227

Mengapa tidak mencoba membuka file? fs.open('YourFile', 'a', function (err, fd) { ... }) bagaimanapun setelah pencarian sebentar coba ini:

var path = require('path'); 

path.exists('foo.txt', function(exists) { 
  if (exists) { 
    // do something 
  } 
}); 

// or 

if (path.existsSync('foo.txt')) { 
  // do something 
} 

Untuk Node.js v0.12.x dan lebih tinggi

Keduanya path.existsdan fs.existstelah ditinggalkan

* Edit:

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

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

Linter mengeluh tentang double sama dengan tidak menjadi triple sama dengan.

Menggunakan 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
Tapi, ternyata fs.existsjuga berhasil. Saya memiliki masalah dengan izin ke file.
RomanGorbatko

11
path.existssebenarnya sudah ditinggalkan demifs.exists
Arnaud Rinquin

42
Siapa pun yang membaca ini sekarang (Node.js v0.12.x) perlu diingat itu fs.existsdan fs.existsSyncjuga telah ditinggalkan. Cara terbaik untuk memeriksa keberadaan file adalah fs.stat, seperti yang ditunjukkan di atas.
Antrikshy

8
Dari dokumentasi Node js, sepertinya cara terbaik untuk pergi jika Anda berencana membuka file setelah memeriksa keberadaannya, adalah dengan benar-benar membukanya dan menangani kesalahan jika tidak ada. Karena file Anda dapat dihapus antara cek yang ada dan fungsi terbuka ...
newprog

6
@Antrikshy fs.existsSynctidak lagi rusak, meskipun fs.existsmasih demikian.
RyanZim

52

Cara yang lebih mudah untuk melakukan ini secara sinkron.

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

Doc API mengatakan cara existsSynckerjanya:
Uji apakah ada jalur yang diberikan dengan memeriksa dengan sistem file.


12
fs.existsSync(path)sudah ditinggalkan sekarang, lihat nodejs.org/api/fs.html#fs_fs_existssync_path . Untuk implementasi yang sinkron fs.statSync(path)disarankan, lihat jawaban saya.
lmeurs

20
@Imeurs tetapi nodejs.org/api/fs.html#fs_fs_existssync_path mengatakan: Perhatikan bahwa fs.exists () sudah usang, tetapi fs.existsSync () tidak.
HaveF

9
fs.existsSyncsudah usang, tetapi tidak lagi.
RyanZim

44

Sunting: Karena simpul v10.0.0dapat kita gunakanfs.promises.access(...)

Contoh kode async yang memeriksa apakah file ada:

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

Alternatif untuk stat mungkin menggunakan yang baru fs.access(...):

fungsi janji pendek yang diperkecil untuk memeriksa:

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

Penggunaan sampel:

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

Cara janji diperluas:

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

atau jika Anda ingin melakukannya secara sinkron:

function checkFileExistsSync(filepath){
  let flag = true;
  try{
    fs.accessSync(filepath, fs.constants.F_OK);
  }catch(e){
    flag = false;
  }
  return flag;
}

1
Terpilih, ini jelas merupakan cara paling modern (2018) untuk mendeteksi jika ada file di Node.js
AKMorris

1
Ya ini adalah metode resmi yang disarankan untuk hanya memeriksa apakah file itu ada dan manipulasi setelahnya tidak diharapkan. Kalau tidak gunakan buka / tulis / baca dan tangani kesalahan. nodejs.org/api/fs.html#fs_fs_stat_path_callback
Justin

1
Dalam dokumentasi yang saya temukan fs.constants.F_OKdll. Apakah mungkin untuk mengaksesnya fs.F_OK? Aneh. Juga singkat, yang bagus.
samson

1
Bisa mencoba melakukannya hanya dengan fs.promises.access(path, fs.constants.F_OK);membuatnya sebagai Janji daripada membuat Janji.
Jeremy Trpka

18

fs.exists(path, callback)dan fs.existsSync(path)sudah tidak digunakan lagi sekarang, lihat https://nodejs.org/api/fs.html#fs_fs_exists_path_callback dan https://nodejs.org/api/fs.html#fs_fs_existsync_path .

Untuk menguji keberadaan file secara sinkron, seseorang dapat menggunakan mis. fs.statSync(path). Sebuah fs.Statsobjek akan dikembalikan jika file ada, lihat https://nodejs.org/api/fs.html#fs_class_fs_stats , jika kesalahan dilemparkan yang akan ditangkap oleh pernyataan try / catch.

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
Tautan yang Anda berikan untuk fs.existsync dengan jelas menunjukkan bahwa ia TIDAK usang "Perhatikan bahwa fs.exists () sudah usang, tetapi fs.existsSync () tidak. (Parameter panggilan balik ke fs.exists () menerima parameter yang tidak konsisten dengan callback Node.js lainnya. fs.existsSync () tidak menggunakan callback.) "
shreddish

jawaban pertama (dari atas), yang menyebutkan dari mana fsvariabel berasal
Dmitry Korolyov

Pada saat jawaban ini ditulis, infonya benar; Namun, fs.existsSync()tidak lagi usang.
RyanZim

12

Versi Lama sebelum V6: inilah dokumentasinya

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

MEMPERBARUI

Versi baru dari V6: dokumentasi untukfs.stat

fs.stat('/etc/passwd', function(err, stat) {
    if(err == null) {
        //Exist
    } else if(err.code == 'ENOENT') {
        // NO exist
    } 
});

1
Keduanya fs.existsdan fs.existsSyncsudah usang menurut tautan yang Anda bagikan.
Andy

existsSynctidak ditinggalkan sesuai dok itu, mungkin itu ketika Anda membacanya.
Darpan

11

Cara async / menunggu modern (Node 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();

Kita perlu menggunakan fs.stat() or fs.access()karena fs.exists(path, callback)sekarang sudah usang

Cara bagus lainnya adalah fs-extra


7

fs.existstelah ditinggalkan sejak 1.0.0. Anda bisa menggunakannya fs.statsebagai gantinya.

var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this 
}  
else { // do this 
}});

Berikut ini tautan untuk dokumentasi fs.stats


stats.isFile()tidak perlu filename.
Wtower

6

@Fox: jawaban yang bagus! Ini sedikit ekstensi dengan beberapa opsi lagi. Ini yang saya gunakan belakangan ini sebagai solusi masuk:

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 periksa fs-extra jika Anda belum menggunakannya-- cukup manis. https://github.com/jprichardson/node-fs-extra )



3

async/awaitversi menggunakan util.promisifypada Node 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

Setelah sedikit bereksperimen, saya menemukan contoh berikut digunakan fs.statuntuk menjadi cara yang baik untuk memeriksa secara asinkron apakah file ada. Itu juga memeriksa bahwa "file" Anda adalah "benar-benar-adalah-file" (dan bukan direktori).

Metode ini menggunakan Janji, dengan asumsi bahwa Anda bekerja dengan basis kode asynchronous:

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

Jika file tersebut tidak ada, janji itu masih akan teratasi, meskipun false. Jika file itu ada, dan itu adalah direktori, maka diselesaikan true. Setiap kesalahan yang mencoba membaca file akan rejectmenjanjikan kesalahan itu sendiri.


1

Yah saya melakukannya dengan cara ini, seperti yang terlihat di https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback

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

Apakah ada masalah dengan ini?


0

di masa lalu sebelum duduk saya selalu memeriksa apakah kursi ada di sana maka saya duduk lagi saya punya rencana alternatif seperti duduk di atas pelatih. Sekarang situs node.js menyarankan pergi saja (tidak perlu memeriksa) dan jawabannya terlihat seperti ini:

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

kode diambil dari http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ mulai Maret 2014, dan sedikit dimodifikasi agar sesuai dengan komputer. Itu memeriksa izin juga - menghapus izin untuk mengujichmod a-r foo.txt


0

panggilan balik 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.
}

yang docs mengatakan Anda harus menggunakan access()sebagai pengganti untuk ditinggalkanexists()

Nodejs dengan build in janji (simpul 7+)

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

Kerangka kerja javascript populer

fs-extra

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

Seperti yang Anda lihat lebih sederhana. Dan kelebihan dari promisify adalah Anda memiliki pengetikan lengkap dengan paket ini (complete intellisense / typescript)! Sebagian besar kasus Anda sudah menyertakan perpustakaan ini karena (+ -10.000) perpustakaan lain bergantung padanya.


0

Anda dapat menggunakan fs.statuntuk memeriksa apakah target adalah file atau direktori dan Anda dapat menggunakan fs.accessuntuk memeriksa apakah Anda dapat menulis / membaca / mengeksekusi file. (ingat untuk menggunakan path.resolveuntuk mendapatkan path lengkap untuk target)

Dokumentasi:

Contoh lengkap (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

Untuk versi asinkron! Dan dengan versi janji! Ini cara bersih dan sederhana!

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

Cuplikan yang lebih praktis dari kode saya untuk menggambarkan lebih baik:


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

Contoh di atas hanya untuk demonstrasi! Saya bisa menggunakan acara kesalahan dari aliran baca! Untuk menangkap kesalahan! Dan lewati dua panggilan!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.