O Node.js verifica se o arquivo existe


143

Como verifico a existência de um arquivo ?

Na documentação do módulo, fshá uma descrição do método fs.exists(path, callback). Mas, pelo que entendi, ele verifica a existência de apenas diretórios. E eu preciso verificar o arquivo !

Como isso pode ser feito?


3
A partir de 2018, use fs.access('file', err => err ? 'does not exist' : 'exists'), consulte fs.access
mb21 12/12/19

Respostas:


227

Por que não apenas tentar abrir o arquivo? fs.open('YourFile', 'a', function (err, fd) { ... }) mesmo assim, após uma pesquisa minuciosa, tente o seguinte:

var path = require('path'); 

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

// or 

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

Para Node.js v0.12.xe superior

Ambos path.existse fs.existsforam preteridos

*Editar:

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

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

Linter reclama que o dobro é igual a não ser o triplo igual.

Usando 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
Mas, como se viu, fs.existstambém funciona. Eu tive problemas com permissões para o arquivo.
RomanGorbatko

11
path.existsna verdade é preterido em favor defs.exists
Arnaud Rinquin

42
Qualquer pessoa que esteja lendo isso agora (Node.js v0.12.x) lembre-se disso fs.existse fs.existsSynctambém foi preterida. A melhor maneira de verificar a existência do arquivo é fs.stat, como demonstrado acima.
Antrikshy

8
Na documentação do Node js, parece o melhor caminho a percorrer, se você planeja abrir o arquivo após verificar sua existência, é realmente abri-lo e manipular os erros se ele não existir. Porque o arquivo pode ser removido entre o seu existe cheque e a função de abertura ...
NewProg

6
@Antrikshy fs.existsSyncnão é mais privado, embora fs.existsainda seja.
RyanZim

52

Uma maneira mais fácil de fazer isso de forma síncrona.

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

O documento da API diz como existsSyncfunciona:
Teste se o caminho fornecido existe ou não, verificando o sistema de arquivos.


12
fs.existsSync(path)está obsoleto agora, consulte nodejs.org/api/fs.html#fs_fs_existssync_path . Para uma implementação síncrona fs.statSync(path)é recomendada, veja minha resposta.
lmeurs 20/09/2015

20
@Imeurs but nodejs.org/api/fs.html#fs_fs_existssync_path diga: Observe que fs.exists () está obsoleto, mas fs.existsSync () não está.
HaveF

9
fs.existsSyncfoi preterido, mas não é mais.
RyanZim

44

Edit: Desde o nó v10.0.0, poderíamos usarfs.promises.access(...)

Exemplo de código assíncrono que verifica se o arquivo existe:

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

Uma alternativa para stat pode estar usando o novo fs.access(...):

função de promessa curta reduzida para verificação:

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

Uso da amostra:

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

Promessa expandida:

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

ou se você quiser fazer isso de forma síncrona:

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

1
Voto positivo, esta é definitivamente a maneira mais moderna (2018) de detectar se existe um arquivo no Node.js
AKMorris

1
Sim, este é o método oficial recomendado para simplesmente verificar se o arquivo existe e a manipulação posterior não é esperada. Caso contrário, use abrir / gravar / ler e manipular o erro. nodejs.org/api/fs.html#fs_fs_stat_path_callback
Justin #

1
Na documentação que encontro fs.constants.F_OKetc. Também é possível acessá-los como fs.F_OK? Esquisito. Também concisa, o que é legal.
21418

1
Poderia tentar fazê-lo com fs.promises.access(path, fs.constants.F_OK);simplesmente torná-lo uma promessa, em vez de criar uma promessa.
Jeremy Trpka

18

fs.exists(path, callback)e fs.existsSync(path)estão obsoletos agora, consulte https://nodejs.org/api/fs.html#fs_fs_exists_path_callback e https://nodejs.org/api/fs.html#fs_fs_existssync_path .

Para testar a existência de um arquivo de forma síncrona, pode-se usar ie. fs.statSync(path). Um fs.Statsobjeto será retornado se o arquivo existir, consulte https://nodejs.org/api/fs.html#fs_class_fs_stats , caso contrário, será gerado um erro que será capturado pela instrução 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
O link que você forneceu para fs.existsync claramente indica que NÃO está obsoleto "Observe que fs.exists () está obsoleto, mas fs.existsSync () não está. (O parâmetro de retorno de chamada para fs.exists () aceita parâmetros inconsistentes com outros retornos de chamada do Node.js. fs.existsSync () não usa retorno de chamada.) "
shreddish

a primeira (do topo) resposta, que mencionado, onde a fsvariável vem
Dmitry Korolyov

No momento em que essa resposta foi escrita, a informação estava correta; no entanto, fs.existsSync()não é mais preterido.
RyanZim

12

Versão antiga antes da V6: aqui está a documentação

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

ATUALIZAR

Novas versões da V6: documentação parafs.stat

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

1
Ambos fs.existse fs.existsSyncforam preteridos de acordo com o link que você compartilhou.
Andy

existsSyncnão é preterido de acordo com esse documento, pode ser que você o tenha lido.
Darpan

11

Maneira assíncrona / aguardada moderna (nó 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();

Precisamos usar fs.stat() or fs.access()porque fs.exists(path, callback)agora está obsoleto

Outra boa maneira é fs-extra


7

fs.existsfoi descontinuado desde 1.0.0. Você pode usar em fs.statvez disso.

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

Aqui está o link para a documentação fs.stats


stats.isFile()não precisa filename.
Wtower 27/09/16

6

@ Fox: ótima resposta! Aqui está um pouco de uma extensão com mais algumas opções. É o que tenho usado ultimamente como uma solução básica:

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, verifique fs-extra se você ainda não o estiver usando - é muito legal. https://github.com/jprichardson/node-fs-extra )



3

async/awaitversão usando util.promisifyno nó 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

Após um pouco de experimentação, encontrei o exemplo a seguir usando fs.stat uma boa maneira de verificar de forma assíncrona se existe um arquivo. Ele também verifica se o seu "arquivo" é "realmente é um arquivo" (e não um diretório).

Este método usa o Promises, assumindo que você esteja trabalhando com uma base de código assíncrona:

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

Se o arquivo não existir, a promessa ainda será resolvida, embora false. Se o arquivo existir e for um diretório, ele será resolvido true. Qualquer erro que tente ler o arquivo rejectpromete o próprio erro.


1

Bem, eu fiz dessa maneira, como pode ser visto em 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');
  }
});

Existe algum problema com isso?


0

antigamente, antes de me sentar, sempre verifico se a cadeira está lá; então, eu me sento; tenho um plano alternativo, como sentar em um treinador. Agora, o site node.js sugere que você vá (não precisa verificar) e a resposta fica assim:

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

código extraído de http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ a partir de março de 2014 e modificado levemente para caber no computador. Ele verifica a permissão também - remove a permissão para testarchmod a-r foo.txt


0

retorno de chamada 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.
}

os documentos dizem que você deve usaraccess() como um substituto para itens obsoletosexists()

Nodejs com promessa de construção (nó 7 ou superior)

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

Estrutura javascript popular

fs-extra

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

Como você vê muito mais simples. E a vantagem sobre o promisify é que você tem digitações completas com este pacote (intellisense completo / texto datilografado)! Na maioria dos casos, você já incluiu esta biblioteca porque (+ -10.000) outras bibliotecas dependem dela.


0

Você pode usar fs.statpara verificar se o destino é um arquivo ou diretório e fs.accesspara verificar se é possível gravar / ler / executar o arquivo. (lembre-se de usar path.resolvepara obter o caminho completo para o destino)

Documentação:

Exemplo completo (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

Para versão assíncrona! E com a versão da promessa! Aqui a maneira simples e limpa!

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

Um trecho mais prático do meu código para ilustrar melhor:


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

O exemplo acima é apenas para demonstração! Eu poderia ter usado o evento de erro do fluxo de leitura! Para pegar algum erro! E pule as duas chamadas!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.