2013-07-17 5 views
94

Как проверить наличие файла?Node.js проверка существует файл

В документации для модуля fs приведено описание метода fs.exists(path, callback). Но, как я понимаю, он проверяет наличие только каталогов. И мне нужно проверить файл !

Как это можно сделать?

+1

Это ничего не говорит о каталогах, не так ли? Он проверяет, существует ли путь.Почему бы вам просто не проверить это самостоятельно, вместо того, чтобы задавать такой вопрос? – Amberlamps

+0

Проверено @Amberlamps. Учитывая, что путь возвращает 'false'. – RomanGorbatko

ответ

170

Почему бы просто не попробовать открыть файл? fs.open('YourFile', 'a', function (err, fd) { ... }) в любом случае после минутного поиска попробовать это:

var path = require('path'); 

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

// or 

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

Для Node.js v0.12.x и выше

Оба path.exists и fs.exists устарели

Использование 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

Но, как оказалось, «fs.exists» тоже работает. У меня были проблемы с правами доступа к файлу. – RomanGorbatko

+9

'path.exists' фактически устарел в пользу' fs.exists' –

+29

Любой, кто сейчас читает это (Node.js v0.12.x), помнит, что 'fs.exists' и' fs.existsSync' также были осуждается. Лучший способ проверить существование файла - 'fs.stat', как показано выше. – Antrikshy

5

@Fox: отличный ответ! Вот немного расширения с некоторыми дополнительными возможностями. Это то, что я использовал в последнее время в качестве готового решения:

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. проверьте fs-extra, если вы еще не используете его - это довольно мило. https://github.com/jprichardson/node-fs-extra)

31

Более простой способ сделать это синхронно.

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

API-интерфейс док говорит, как existsSync работы:
испытания, существует ли данный путь, проверяя с файловой системой.

+8

'fs.existsSync (path)' устарел сейчас, см. Https://nodejs.org/api/fs.html#fs_fs_existssync_path. Для синхронной реализации 'fs.statSync (path)' рекомендуется, см. Мой ответ. – lmeurs

+0

Imeurs, Спасибо за информацию. Это правильно –

+8

@Imeurs, но https://nodejs.org/api/fs.html#fs_fs_existssync_path сказать: Обратите внимание, что fs.exists() устарел, но fs.existsSync() - нет. – HaveF

0

в старые времена, прежде чем сесть. Я всегда проверяю, есть ли там стул, тогда я сижу еще. У меня есть альтернативный план, как сидеть на тренере. Теперь node.js сайт предлагает просто идти (нет нужды, чтобы проверить) и ответ выглядит следующим образом:

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

код взят из http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ с марта 2014 года, и немного изменен, чтобы соответствовать компьютеру. Он проверяет разрешения, а также - удалить разрешение испытать chmod a-r foo.txt

16

fs.exists(path, callback) и fs.existsSync(path) устарели сейчас, см https://nodejs.org/api/fs.html#fs_fs_exists_path_callback и https://nodejs.org/api/fs.html#fs_fs_existssync_path.

Чтобы проверить наличие файла синхронно, можно использовать ie. fs.statSync(path). Объект fs.Stats будет возвращен, если файл существует, см. https://nodejs.org/api/fs.html#fs_class_fs_stats, в противном случае возникает ошибка, которая будет улавливаться оператором 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."); 
} 
+5

Ссылка, которую вы предоставили для fs.existsync, явно указывает, что она НЕ устарела «Обратите внимание, что fs.exists() устарел, но fs.existsSync() не является. (Параметр обратного вызова для fs.exists() принимает параметры которые несовместимы с другими обратными вызовами Node.js. fs.existsSync() не использует обратный вызов.) « – shreddish

+0

первый (сверху) ответ, в котором упоминается, где переменная' fs' поступает из – user907860

+0

. В то время, когда этот ответ был написано, информация была правильной; однако 'fs.existsSync()' больше не устарел. – RyanZim

18

Альтернатива стата может быть с помощью нового fs.access(...):

уменьшенной короткой функции посыла для проверки: использование

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

Примера:

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

расширил Promise путь:

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

или если вы хотите сделать это синхронно:

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

Упомянутый, это, безусловно, самый современный (2018) способ определить, существует ли файл в Node.js – AKMorris

+0

Да, это официальный рекомендованный метод, чтобы просто проверить, существует ли файл и какие манипуляции впоследствии не ожидается. В противном случае используйте open/write/read и обработайте ошибку. https://nodejs.org/api/fs.html#fs_fs_stat_path_callback – Justin

+0

В документации я нахожу 'fs.constants.F_OK' и т. д. Можно ли также получить к ним доступ как' fs.F_OK'? Weird. Также кратким, что приятно. – samson

7

fs.exists устарела начиная с версии 1.0.0. Вместо этого вы можете использовать fs.stat.

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

Вот ссылка для документации fs.stats

+0

Этот код даже не работает –

+0

'stats.isFile()' не нужно 'filename'. – Wtower

1

Ну, я сделал это так, как показано на 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'); 
    } 
}); 

Есть ли какие-либо проблемы с этим?

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

старую версию перед V6: here's the documentation

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

Новые версии от V6: documentation for fs.stat

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

И 'fs.exists', и' fs.existsSync' устарели в соответствии с общей вами ссылкой. – Andy

+0

'existsSync' не устарел в соответствии с этим документом, возможно, это было, когда вы его читали. – Darpan

1

После недолгих экспериментов, я нашел следующий пример с использованием fs.stat, чтобы быть хорошим способом асинхронной проверки наличия файла. Он также проверяет, что ваш «файл» - «действительно-есть-файл» (а не каталог).

Этот метод использует посылы, при условии, что вы работаете с асинхронным кодовую:

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

Если файл не существует, обещание до сих пор решает, хотя false. Если файл существует и является каталогом, то он разрешает true. Любые ошибки, пытающиеся прочитать файл, будут reject обещанием самой ошибки.

-1

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

docs говорят, что вы должны использовать access() в качестве замены для устаревших exists()

Nodejs со встроенным обещанию (узел 7+)

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

Популярные JavaScript рамки

fs-extra

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

Как вы видите, гораздо проще. И преимущество перед обещанием состоит в том, что у вас есть полное типирование с этим пакетом (полный intellisense/typescript)! В большинстве случаев вы уже включили эту библиотеку, потому что (+ -10.000) другие библиотеки зависят от нее.

1

async/await версия, использующая util.promisify от узла 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); 
    } 
    }); 
}); 
0

Вы можете использовать fs.stat, чтобы проверить, если целевой файл или каталог, и вы можете использовать fs.access, чтобы проверить, если вы можете писать/читать/выполнение файл. (Не забудьте использовать path.resolve, чтобы получить полный путь к цели)

Документация:

Полный пример (машинопись)

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); 
}()); 
Смежные вопросы