Bagaimana cara saya memeriksa, menggunakan node.js , jika ada file atau direktori?
exists
hanya menambahkan panggilan balik yang tidak perlu.
Bagaimana cara saya memeriksa, menggunakan node.js , jika ada file atau direktori?
exists
hanya menambahkan panggilan balik yang tidak perlu.
Jawaban:
Jawaban atas pertanyaan ini telah berubah selama bertahun-tahun. The sekarang jawabannya di sini di bagian atas, diikuti oleh berbagai jawaban selama bertahun-tahun secara kronologis:
Anda bisa menggunakan fs.existsSync()
:
const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
// Do something
}
Itu sudah ditinggalkan selama beberapa tahun, tetapi tidak lagi. Dari dokumen:
Perhatikan bahwa
fs.exists()
sudah usang, tetapifs.existsSync()
tidak. (Parameter panggilan balik untukfs.exists()
menerima parameter yang tidak konsisten dengan panggilan balik Node.js lainnya.fs.existsSync()
Tidak menggunakan panggilan balik.)
Anda telah secara spesifik meminta pemeriksaan sinkron , tetapi jika Anda dapat menggunakan pemeriksaan asinkron sebagai gantinya (biasanya terbaik dengan I / O), gunakan fs.promises.access
jika Anda menggunakan async
fungsi atau fs.access
(karena exists
sudah usang ) jika tidak:
Dalam suatu async
fungsi:
try {
await fs.promises.access("somefile");
// The check succeeded
} catch (error) {
// The check failed
}
Atau dengan panggilan balik:
fs.access("somefile", error => {
if (!error) {
// The check succeeded
} else {
// The check failed
}
});
Berikut adalah jawaban historis dalam urutan kronologis:
stat
/ statSync
atau lstat
/ lstatSync
)exists
/ existsSync
)exists
/ existsSync
, jadi kami mungkin kembali ke stat
/ statSync
atau lstat
/ lstatSync
)fs.access(path, fs.F_OK, function(){})
/ fs.accessSync(path, fs.F_OK)
, tetapi perhatikan bahwa jika file / direktori tidak ada, itu adalah kesalahan; dokumen untuk fs.stat
direkomendasikan digunakan fs.access
jika Anda perlu memeriksa keberadaan tanpa membuka)fs.exists()
masih usang tetapi fs.existsSync()
tidak lagi ditinggalkan. Jadi Anda bisa menggunakannya dengan aman sekarang.Anda dapat menggunakan statSync
atau lstatSync
( tautan dokumen ), yang memberi Anda sebuah fs.Stats
objek . Secara umum, jika versi sinkron dari suatu fungsi tersedia, ia akan memiliki nama yang sama dengan versi async Sync
di bagian akhir. Begitu statSync
juga dengan versi sinkron stat
; lstatSync
adalah versi sinkron lstat
, dll.
lstatSync
memberi tahu Anda apakah sesuatu itu ada, dan jika demikian, apakah itu file atau direktori (atau dalam beberapa sistem file, tautan simbolis, perangkat blok, perangkat karakter, dll.), mis. jika Anda perlu tahu apakah itu ada dan direktori:
var fs = require('fs');
try {
// Query the entry
stats = fs.lstatSync('/the/path');
// Is it a directory?
if (stats.isDirectory()) {
// Yes it is
}
}
catch (e) {
// ...
}
... dan juga, jika itu file, ada isFile
; jika itu adalah perangkat blok, ada isBlockDevice
, dll., dll. Perhatikan try/catch
; ia melempar kesalahan jika entri tidak ada sama sekali.
Jika Anda tidak peduli apa entri itu dan hanya ingin tahu apakah itu ada, Anda dapat menggunakan path.existsSync
(atau dengan yang terbaru fs.existsSync
) , seperti yang dicatat oleh user618408 :
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
Itu tidak memerlukan try/catch
tetapi tidak memberi Anda informasi tentang apa masalahnya, hanya saja ada di sana. path.existsSync
sudah lama ditinggalkan.
Catatan: Anda telah secara jelas bertanya bagaimana cara memeriksa secara sinkron , jadi saya telah menggunakan xyzSync
versi fungsi di atas. Tetapi sedapat mungkin, dengan I / O, yang terbaik adalah menghindari panggilan sinkron. Panggilan ke subsistem I / O membutuhkan waktu yang signifikan dari sudut pandang CPU. Perhatikan betapa mudahnya menelepon lstat
daripada lstatSync
:
// Is it a directory?
lstat('/the/path', function(err, stats) {
if (!err && stats.isDirectory()) {
// Yes it is
}
});
Tetapi jika Anda membutuhkan versi sinkron, itu ada di sana.
Jawaban di bawah ini dari beberapa tahun yang lalu sekarang agak ketinggalan zaman. Cara saat ini adalah menggunakan fs.existsSync
untuk melakukan pemeriksaan sinkron untuk keberadaan file / direktori (atau tentu saja fs.exists
untuk pemeriksaan tidak sinkron), daripada path
versi di bawah ini.
Contoh:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
Dan inilah kita pada tahun 2015 dan Node docs sekarang mengatakan bahwa fs.existsSync
(dan fs.exists
) "akan ditinggalkan". (Karena orang-orang Node berpikir bodoh untuk memeriksa apakah ada sesuatu sebelum membukanya, itu memang benar; tetapi itu bukan satu-satunya alasan untuk memeriksa apakah ada sesuatu!)
Jadi kita mungkin kembali ke berbagai stat
metode ... Sampai / kecuali ini berubah lagi, tentu saja.
Tidak tahu berapa lama sudah ada, tapi ada juga fs.access(path, fs.F_OK, ...)
/fs.accessSync(path, fs.F_OK)
. Dan setidaknya pada Oktober 2016, fs.stat
dokumentasi merekomendasikan penggunaan fs.access
untuk melakukan pemeriksaan keberadaan ( "Untuk memeriksa apakah ada file tanpa memanipulasi sesudahnya, fs.access()
disarankan." ). Tetapi perhatikan bahwa akses yang tidak tersedia dianggap kesalahan , jadi ini mungkin yang terbaik jika Anda mengharapkan file dapat diakses:
var fs = require('fs');
try {
fs.accessSync(path, fs.F_OK);
// Do something
} catch (e) {
// It isn't accessible
}
// Or
fs.access(path, fs.F_OK, function(err) {
if (!err) {
// Do something
} else {
// It isn't accessible
}
});
Anda bisa menggunakan fs.existsSync()
:
if (fs.existsSync(path)) {
// Do something
}
Itu sudah ditinggalkan selama beberapa tahun, tetapi tidak lagi. Dari dokumen:
Perhatikan bahwa
fs.exists()
sudah usang, tetapifs.existsSync()
tidak. (Parameter panggilan balik untukfs.exists()
menerima parameter yang tidak konsisten dengan panggilan balik Node.js lainnya.fs.existsSync()
Tidak menggunakan panggilan balik.)
open
panggilan dan menangani pengecualian atau apa pun jika file tidak ditemukan. Lagipula, dunia nyata kacau: Jika Anda memeriksa dulu dan itu ada di sana, itu tidak berarti itu akan tetap ada ketika Anda mencoba membukanya; jika Anda memeriksa dulu dan tidak ada di sana, itu tidak berarti itu tidak akan ada di sana beberapa saat kemudian. Mengatur waktu hal-hal seperti itu tampak seperti kasus tepi, tetapi mereka muncul setiap saat . Jadi jika Anda akan membuka, tidak ada gunanya memeriksa dulu.
Melihat sumbernya, ada versi sinkron dari path.exists
- path.existsSync
. Sepertinya itu terlewatkan dalam dokumen.
path.exists
dan path.existsSync
sekarang sudah usang . Silakan gunakan .fs.exists
danfs.existsSync
fs.exists
dan sudah usang . Gunakan fs.stat () atau fs.access () sebagai gantinya.fs.existsSync
juga
gunakan fs.existsSync
. Itu tidak ditinggalkan.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
fs.existsSync
.
exists
fungsi lama :is-there
fs.exists
sebagai usang sementara fs.existsSync
tidak!
Menggunakan API yang saat ini direkomendasikan (per 2015) (per Node docs), inilah yang saya lakukan:
var fs = require('fs');
function fileExists(filePath)
{
try
{
return fs.statSync(filePath).isFile();
}
catch (err)
{
return false;
}
}
Menanggapi masalah EPERM yang diangkat oleh @broadband dalam komentar, itu memunculkan poin yang bagus. fileExists () mungkin bukan cara yang baik untuk memikirkan hal ini dalam banyak kasus, karena fileExists () tidak dapat benar-benar menjanjikan pengembalian boolean. Anda mungkin dapat menentukan secara pasti bahwa file itu ada atau tidak ada, tetapi Anda juga bisa mendapatkan kesalahan izin. Kesalahan izin tidak selalu menyiratkan bahwa file itu ada, karena Anda bisa kekurangan izin ke direktori yang berisi file yang Anda periksa. Dan tentu saja ada kemungkinan Anda bisa menemukan kesalahan lain dalam memeriksa keberadaan file.
Jadi kode saya di atas benar-benar doesFileExistAndDoIHaveAccessToIt (), tetapi pertanyaan Anda mungkin apakahFileNotExistAndCouldICreateIt (), yang akan menjadi logika yang sangat berbeda (yang perlu memperhitungkan kesalahan EPERM, antara lain).
Sementara jawaban fs.existsSync menjawab pertanyaan yang diajukan langsung di sini, itu seringkali tidak sesuai dengan yang Anda inginkan (Anda tidak hanya ingin tahu apakah "sesuatu" ada di jalur, Anda mungkin peduli apakah "benda" itu ada. yang ada adalah file atau direktori).
Intinya adalah bahwa jika Anda memeriksa untuk melihat apakah ada file, Anda mungkin melakukan itu karena Anda berniat untuk mengambil beberapa tindakan berdasarkan hasil, dan bahwa logika (pemeriksaan dan / atau tindakan selanjutnya) harus mengakomodasi ide bahwa sesuatu yang ditemukan di jalur itu mungkin berupa file atau direktori, dan bahwa Anda mungkin menemui EPERM atau kesalahan lain dalam proses pemeriksaan.
file.exists()
util sederhana untuk 3% dan bukannya memaksa kita untuk membungkus ini dalam try catch? Dapatkan nyata ... Pelacur hari ini.
Pembaruan lain
Membutuhkan jawaban untuk pertanyaan ini sendiri, saya mencari node docs, sepertinya Anda tidak boleh menggunakan fs.exists, alih-alih gunakan fs.open dan gunakan kesalahan yang dihasilkan untuk mendeteksi jika file tidak ada:
dari dokumen:
fs.exists () adalah anakronisme dan hanya ada karena alasan historis. Seharusnya hampir tidak pernah ada alasan untuk menggunakannya dalam kode Anda sendiri.
Khususnya, memeriksa apakah ada file sebelum membukanya, ini merupakan pola-anti yang membuat Anda rentan terhadap kondisi balapan: proses lain dapat menghapus file di antara panggilan ke fs.exists () dan fs.open (). Cukup buka file dan tangani kesalahannya saat tidak ada.
Saya menggunakan fungsi di bawah ini untuk menguji apakah ada file. Itu juga menangkap pengecualian lain. Jadi jika ada masalah hak misalnya chmod ugo-rwx filename
atau dalam Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
fungsi Windows
mengembalikan pengecualian sebagaimana mestinya. File ada tetapi kami tidak memiliki hak untuk mengaksesnya. Adalah salah untuk mengabaikan pengecualian semacam ini.
function fileExists(path) {
try {
return fs.statSync(path).isFile();
}
catch (e) {
if (e.code == 'ENOENT') { // no such file or directory. File really does not exist
console.log("File does not exist.");
return false;
}
console.log("Exception fs.statSync (" + path + "): " + e);
throw e; // something else went wrong, we don't have rights, ...
}
}
Output pengecualian, dokumentasi kesalahan simpuljs dalam file kasus tidak ada:
{
[Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'stat',
path: 'X:\\delsdfsdf.txt'
}
Pengecualian jika kami tidak memiliki hak atas file tersebut, tetapi ada:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
fs.exists () sudah usang jangan menggunakannya https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Anda bisa mengimplementasikan cara simpuljs inti yang digunakan di ini: https://github.com/nodejs/node-v0.x-archive/blob/master/lib/module.js#L86
function statPath(path) {
try {
return fs.statSync(path);
} catch (ex) {}
return false;
}
ini akan mengembalikan objek statistik maka setelah Anda mendapatkan objek statistik yang bisa Anda coba
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
Beberapa jawaban di sini mengatakan itu fs.exists
dan fs.existsSync
keduanya sudah usang. Menurut dokumen ini tidak lagi benar. Hanya fs.exists
depreksi sekarang:
Perhatikan bahwa fs.exists () sudah usang, tetapi fs.existsSync () tidak. (Parameter panggilan balik ke fs.exists () menerima parameter yang tidak konsisten dengan panggilan balik Node.js lainnya. Fs.existsSync () tidak menggunakan panggilan balik.)
Jadi Anda dapat menggunakan fs.existsSync () dengan aman untuk memeriksa apakah ada file.
The path
modul tidak menyediakan versi sinkron path.exists
sehingga Anda harus mengelabui sekitar dengan fs
modul.
Hal tercepat yang dapat saya bayangkan adalah menggunakan fs.realpathSync
yang akan melempar kesalahan yang harus Anda tangkap, jadi Anda harus membuat fungsi pembungkus sendiri dengan mencoba / menangkap.
Menggunakan tes fileSystem (fs) akan memicu objek kesalahan, yang kemudian harus Anda bungkus dalam pernyataan try / catch. Simpan upaya Anda sendiri, dan gunakan fitur pengantar di cabang 0.4.x.
var path = require('path');
var dirs = ['one', 'two', 'three'];
dirs.map(function(dir) {
path.exists(dir, function(exists) {
var message = (exists) ? dir + ': is a directory' : dir + ': is not a directory';
console.log(message);
});
});
Dokumen di fs.stat()
mengatakan untuk digunakan fs.access()
jika Anda tidak akan memanipulasi file. Itu tidak memberikan pembenaran, mungkin lebih cepat atau kurang memeory digunakan?
Saya menggunakan simpul untuk otomatisasi linier, jadi saya pikir saya berbagi fungsi yang saya gunakan untuk menguji keberadaan file.
var fs = require("fs");
function exists(path){
//Remember file access time will slow your program.
try{
fs.accessSync(path);
} catch (err){
return false;
}
return true;
}
diperbarui asnwer untuk orang-orang 'benar' menunjukkan itu tidak langsung menjawab pertanyaan, lebih banyak membawa opsi alternatif.
fs.existsSync('filePath')
lihat juga dokumen di sini .
Mengembalikan nilai true jika path ada, false jika tidak.
Dalam konteks async Anda hanya bisa menulis versi async dalam metode sinkronisasi dengan menggunakan await
kata kunci. Anda bisa mengubah metode panggilan balik async menjadi janji seperti ini:
function fileExists(path){
return new Promise((resolve, fail) => fs.access(path, fs.constants.F_OK,
(err, result) => err ? fail(err) : resolve(result))
//F_OK checks if file is visible, is default does no need to be specified.
}
async function doSomething() {
var exists = await fileExists('filePath');
if(exists){
console.log('file exists');
}
}
dokumen tentang akses ().
function asyncFileExists(path) { //F_OK checks if file is visible, is default does no need to be specified. return new Promise(function (res, rej) { fs.access( path, fs.constants.F_OK, function (err) { err ? rej(err) : res(true); }, ); }); }
Kemungkinannya adalah, jika Anda ingin tahu apakah ada file, Anda berencana untuk meminta jika ada.
function getFile(path){
try{
return require(path);
}catch(e){
return false;
}
}
Berikut ini adalah solusi pembungkus sederhana untuk ini:
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
Pemakaian:
Contoh:
var realPath,pathToCheck='<your_dir_or_file>'
if( (realPath=getFileRealPath(pathToCheck)) === false){
console.log('file/dir not found: '+pathToCheck);
} else {
console.log('file/dir exists: '+realPath);
}
Pastikan Anda menggunakan operator === untuk menguji apakah return sama dengan false. Tidak ada alasan logis bahwa fs.realpathSync () akan mengembalikan false di bawah kondisi kerja yang tepat, jadi saya pikir ini harus bekerja 100%.
Saya lebih suka melihat solusi yang tidak menghasilkan Kesalahan dan mengakibatkan hit kinerja. Dari perspektif API, fs.exists () sepertinya solusi paling elegan.
Dari jawaban, tampaknya tidak ada dukungan API resmi untuk ini (seperti dalam pemeriksaan langsung dan eksplisit). Banyak jawaban mengatakan menggunakan stat, namun tidak ketat. Sebagai contoh, kita tidak dapat berasumsi bahwa kesalahan yang dibuat oleh stat berarti ada sesuatu yang tidak ada.
Katakanlah kita mencobanya dengan sesuatu yang tidak ada:
$ node -e 'require("fs").stat("god",err=>console.log(err))'
{ Error: ENOENT: no such file or directory, stat 'god' errno: -2, code: 'ENOENT', syscall: 'stat', path: 'god' }
Mari kita coba dengan sesuatu yang ada tetapi kita tidak memiliki akses ke:
$ mkdir -p fsm/appendage && sudo chmod 0 fsm
$ node -e 'require("fs").stat("fsm/appendage",err=>console.log(err))'
{ Error: EACCES: permission denied, stat 'access/access' errno: -13, code: 'EACCES', syscall: 'stat', path: 'fsm/appendage' }
Paling tidak Anda akan menginginkan:
let dir_exists = async path => {
let stat;
try {
stat = await (new Promise(
(resolve, reject) => require('fs').stat(path,
(err, result) => err ? reject(err) : resolve(result))
));
}
catch(e) {
if(e.code === 'ENOENT') return false;
throw e;
}
if(!stat.isDirectory())
throw new Error('Not a directory.');
return true;
};
Pertanyaannya tidak jelas apakah Anda benar-benar ingin sinkron atau jika Anda hanya ingin itu ditulis seolah-olah sinkron. Contoh ini menggunakan await / async sehingga hanya ditulis secara sinkron tetapi berjalan secara asinkron.
Ini berarti Anda harus menyebutnya seperti itu di tingkat atas:
(async () => {
try {
console.log(await dir_exists('god'));
console.log(await dir_exists('fsm/appendage'));
}
catch(e) {
console.log(e);
}
})();
Alternatif menggunakan .then dan .catch pada janji yang dikembalikan dari panggilan async jika Anda membutuhkannya lebih jauh.
Jika Anda ingin memeriksa apakah ada sesuatu maka itu praktik yang baik untuk juga memastikan itu adalah jenis yang tepat seperti direktori atau file. Ini termasuk dalam contoh. Jika tidak diizinkan menjadi symlink, Anda harus menggunakan lstat daripada stat karena stat akan secara otomatis melintasi tautan.
Anda dapat mengganti semua async untuk menyinkronkan kode di sini dan menggunakan statSync sebagai gantinya. Namun berharap bahwa begitu async dan menunggu menjadi universal mendukung panggilan Sync akan menjadi berlebihan pada akhirnya akan didepresiasi (jika tidak, Anda harus mendefinisikannya di mana-mana dan menaiki rantai seperti halnya async sehingga membuatnya benar-benar tidak ada gunanya).