Bir dosya veya dizinin mevcut olup olmadığını node.js kullanarak nasıl eşzamanlı olarak denetleyebilirim ?
exists
yalnızca gereksiz geri aramalar ekler.
Bir dosya veya dizinin mevcut olup olmadığını node.js kullanarak nasıl eşzamanlı olarak denetleyebilirim ?
exists
yalnızca gereksiz geri aramalar ekler.
Yanıtlar:
Bu sorunun cevabı yıllar içinde değişti. Geçerli cevap kronolojik sırayla yıllar boyunca çeşitli cevaplar, ardından üst kısmında buradadır:
Şunları kullanabilirsiniz fs.existsSync()
:
const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
// Do something
}
Birkaç yıl boyunca kullanımdan kaldırıldı, ancak artık yok. Dokümanlardan:
Not
fs.exists()
kullanımdan kaldırıldı, ancakfs.existsSync()
değil. (fs.exists()
Diğer Node.js geri çağrılarıyla tutarsız parametreleri kabul etmek için geri çağrı parametresi . Geri aramafs.existsSync()
kullanmaz.)
Özellikle eşzamanlı kontrol istediniz , ancak bunun yerine eşzamansız bir kontrol kullanabiliyorsanız (genellikle G / Ç ile en iyisi), işlevler fs.promises.access
kullanıyorsanız async
veya kullanılmadığı için fs.access
( exists
kullanımdan kaldırıldığı için ) kullanın:
Bir async
işlevde:
try {
await fs.promises.access("somefile");
// The check succeeded
} catch (error) {
// The check failed
}
Veya geri arama ile:
fs.access("somefile", error => {
if (!error) {
// The check succeeded
} else {
// The check failed
}
});
İşte tarihsel cevaplar kronolojik sırada:
stat
/ statSync
veya lstat
/ lstatSync
)exists
/ existsSync
)exists
/ 'in kullanımdan kaldırıldığına dikkat edin existsSync
, bu nedenle muhtemelen stat
/ statSync
veya lstat
/' ya geri döndük lstatSync
)fs.access(path, fs.F_OK, function(){})
/ fs.accessSync(path, fs.F_OK)
, ancak dosya / dizin yoksa bir hata olduğunu unutmayın; açmadan varlığını kontrol etmeniz gerekiyorsa fs.stat
kullanılmasını öneren dokümanlar fs.access
)fs.exists()
hala kullanımdan kaldırıldı fs.existsSync()
, ancak artık kullanımdan kaldırılmıyor. Böylece şimdi güvenle kullanabilirsiniz.Size bir nesne veren statSync
veya lstatSync
( dokümanlar bağlantısı ) kullanabilirsiniz . Genel olarak, bir işlevin eşzamanlı sürümü varsa , sonunda eşzamansız sürümle aynı ada sahip olacaktır . Yani eşzamanlı sürümü ; eşzamanlı sürümüdür , vb.fs.Stats
Sync
statSync
stat
lstatSync
lstat
lstatSync
hem bir şeyin var olup olmadığını hem de bir dosya veya dizin (ya da bazı dosya sistemlerinde, sembolik bir bağlantı, blok cihaz, karakter cihazı vb.) olup olmadığını, örneğin var olup olmadığını bilmeniz gerekiyorsa bir dizin:
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) {
// ...
}
... ve benzer şekilde, eğer bir dosya ise isFile
; bir blok cihazı varsa isBlockDevice
, vb. vardır try/catch
. giriş hiç yoksa bir hata atar.
Eğer giriş umurumda değil ise ise ve yalnızca kullanabileceğiniz var olup olmadığını bilmek istiyorum path.existsSync
(en son birlikte veya fs.existsSync
gibi) user618408 tarafından da belirtildiği :
var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
// ...
}
Bir şey gerektirmez, try/catch
ancak şeyin ne olduğu hakkında hiçbir bilgi vermez, sadece oradadır. path.existsSync
uzun zaman önce kullanımdan kaldırıldı.
Yan not: Eşzamanlı olarak nasıl kontrol edeceğinizi açıkça sordunuz , bu nedenle xyzSync
yukarıdaki işlevlerin sürümlerini kullandım . Ancak, mümkün olan her yerde, G / Ç ile, senkron çağrılardan kaçınmak en iyisidir. I / O alt sistemine yapılan aramalar CPU açısından önemli zaman alır. Aramak lstat
yerine aramanın ne kadar kolay olduğuna dikkat edin lstatSync
:
// Is it a directory?
lstat('/the/path', function(err, stats) {
if (!err && stats.isDirectory()) {
// Yes it is
}
});
Ancak senkron versiyona ihtiyacınız varsa, orada.
Birkaç yıl önceki aşağıdaki cevap şimdi biraz güncel değil. Geçerli yol, aşağıdaki sürümler yerine fs.existsSync
dosya / dizin varlığı (veya elbette fs.exists
eşzamansız bir denetim için) için eşzamanlı denetim yapmaktır path
.
Misal:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
Ve burada 2015'teyiz ve Düğüm dokümanları artık fs.existsSync
(ve fs.exists
) "kullanımdan kaldırılacak" diyor. (Çünkü Düğüm insanları bir şeyin açılmadan önce var olup olmadığını kontrol etmenin aptal olduğunu düşünüyorlar, ki öyle; ama bir şeyin var olup olmadığını kontrol etmenin tek nedeni bu değil!)
Muhtemelen çeşitli stat
yöntemlere geri dönüyoruz ... Tabii bu yine değişmedikçe / sürece.
Ne kadar süredir orada olduğunu bilmiyorum, ama ayrıca fs.access(path, fs.F_OK, ...)
/fs.accessSync(path, fs.F_OK)
. Ve en azından Ekim 2016'dan itibaren, fs.stat
belgelerfs.access
varoluş kontrolleri yapmayı önerir ( "Bir dosyanın daha sonra manipüle etmeden var olup olmadığını kontrol etmek fs.access()
için önerilir." ). Ancak, erişilemeyen erişimin bir hata olarak kabul edildiğini unutmayın; bu nedenle, dosyanın erişilebilir olmasını bekliyorsanız muhtemelen en iyisi olacaktır:
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
}
});
Şunları kullanabilirsiniz fs.existsSync()
:
if (fs.existsSync(path)) {
// Do something
}
Birkaç yıl boyunca kullanımdan kaldırıldı, ancak artık yok. Dokümanlardan:
Not
fs.exists()
kullanımdan kaldırıldı, ancakfs.existsSync()
değil. (fs.exists()
Diğer Node.js geri çağrılarıyla tutarsız parametreleri kabul etmek için geri çağrı parametresi . Geri aramafs.existsSync()
kullanmaz.)
open
istisna ya da her türlü dosya değilse çağrıyı ve idare bulundu. Sonuçta, gerçek dünya kaotiktir: Önce kontrol ederseniz ve oradaysa, açmaya çalıştığınızda hala orada olacağı anlamına gelmez; önce kontrol ederseniz ve orada değilse, bu bir an sonra orada olmayacağı anlamına gelmez. Bu gibi şeyleri zamanlamak son durumlara benziyor, ama her zaman ortaya çıkıyorlar . Yani eğer sen açacaksın, ilk kontrol anlamı yok.
Kaynağında baktığımızda, bir senkron versiyonu var path.exists
- path.existsSync
. Belgelerde kaçırılmış gibi görünüyor.
path.exists
ve path.existsSync
artık kullanımdan kaldırıldı . Lütfen .fs.exists
ve kullanınfs.existsSync
fs.exists
ve kullanımdan kaldırıldı . Kullanım fs.stat () veya fs.access () yerine.fs.existsSync
ayrıca
kullanın fs.existsSync
. Onaylanmadı.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
fs.existsSync
.
exists
işlevi değiştirmek için küçük bir kütüphane yazdım :is-there
fs.exists
kullanımdan kaldırılmış olarak etiketlenir fs.existsSync
değil!
Şu anda önerilen (2015 itibariyle) API'ları (Düğüm belgelerine göre) kullanarak, yaptığım şey bu:
var fs = require('fs');
function fileExists(filePath)
{
try
{
return fs.statSync(filePath).isFile();
}
catch (err)
{
return false;
}
}
Yorumlarda @broband tarafından ortaya atılan EPERM sorununa yanıt olarak bu iyi bir noktaya işaret ediyor. fileExists () muhtemelen birçok durumda bunu düşünmek için iyi bir yol değildir, çünkü fileExists () gerçekten bir boole dönüşü vaat edemez. Dosyanın var olup olmadığını kesin olarak belirleyebilir, ancak bir izin hatası da alabilirsiniz. İzinler hatası mutlaka dosyanın var olduğu anlamına gelmez, çünkü kontrol ettiğiniz dosyayı içeren dizine izin veremeyebilirsiniz. Ve elbette dosya varlığını kontrol etmede başka bir hatayla karşılaşma şansı var.
Bu yüzden yukarıdaki kodum gerçekten doesFileExistAndDoIHaveAccessToIt (), ancak sorunuz diğer şeylerin yanı sıra tamamen farklı bir mantık (bu bir EPERM hatasını hesaba katması gerekecek) doesFileNotExistAndCouldICreateIt () olabilir.
Fs.existsSync yanıtı burada doğrudan sorulan soruyu ele alırken, bu genellikle istediğiniz şey değildir (sadece bir yolda "bir şey" olup olmadığını bilmek istemezsiniz, muhtemelen "şey" in varolan bir dosya veya dizindir).
Sonuç olarak, bir dosyanın var olup olmadığını kontrol ediyorsanız, muhtemelen sonuca göre bazı eylemlerde bulunmayı planladığınızdan ve bu mantığın (kontrol ve / veya sonraki eylem) fikri barındırması gerektiğinden bu yolda bulunan bir şeyin bir dosya veya dizin olabileceğini ve kontrol sürecinde EPERM veya diğer hatalarla karşılaşabileceğinizi unutmayın.
file.exists()
% 3 için basit bir util sahip değil ve bunun yerine bir deneyin yakalamak sarmak için bizi zorluyor? Gerçek ol ... Günün kaltak.
Başka Bir Güncelleme
Bu soruya kendim cevap ihtiyacın Ben düğüm docs baktım, sen gerektiğini görünüyor değil bir dosya yoksa algılamak için fs.open kullanabilir ve outputted hatayı kullanmak yerine, fs.exists kullanıyor:
dokümanlardan:
fs.exists (), bir anakronizmdir ve yalnızca tarihsel nedenlerle bulunur. Kendi kodunuzda kullanmak için neredeyse hiçbir zaman bir sebep olmamalıdır.
Özellikle, bir dosyayı açmadan önce var olup olmadığını kontrol etmek, sizi yarış koşullarına karşı savunmasız bırakan bir anti-kalıptır: başka bir işlem, fs.exists () ve fs.open () çağrıları arasındaki dosyayı kaldırabilir. Sadece dosyayı açın ve orada olmadığında hatayı halledin.
Dosyanın var olup olmadığını test etmek için aşağıdaki işlevi kullanıyorum. Diğer istisnaları da yakalar. Bu nedenle, örneğin hak sorunları olması chmod ugo-rwx filename
veya Windows
Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
işlevinde olması gerektiği gibi istisna döndürür. Dosya var, ancak dosyaya erişim hakkımız yok. Bu tür istisnaları göz ardı etmek yanlış olur.
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, ...
}
}
İstisna çıktısı, dosya yoksa nodejs hata belgeleri :
{
[Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'stat',
path: 'X:\\delsdfsdf.txt'
}
Dosyayla ilgili haklarımız olmadığı, ancak var olduğu durumlar hariç:
{
[Error: EPERM: operation not permitted, stat 'X:\file.txt']
errno: -4048,
code: 'EPERM',
syscall: 'stat',
path: 'X:\\file.txt'
}
fs.exists () kullanımdan kaldırıldı kullanma https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Burada kullanılan temel nodejs yolunu uygulayabilirsiniz: 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;
}
bu durum istatistik nesnesini döndürür ve ardından istatistik nesnesini aldıktan sonra deneyebilirsiniz
var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
// do something
}
Buradaki bazı cevaplar bunu söylüyor fs.exists
ve fs.existsSync
ikisi de kullanımdan kaldırılıyor. Dokümanlara göre bu artık doğru değil. Yalnızca fs.exists
şu anda reddedildi:
Fs.exists () öğesinin kullanımdan kaldırıldığını, ancak fs.existsSync () öğesinin kullanılmadığını unutmayın. (Fs.exists () öğesinin geri çağırma parametresi, diğer Node.js geri çağrılarıyla tutarsız olan parametreleri kabul eder. Fs.existsSync (), geri çağrı kullanmaz.)
Böylece , bir dosyanın var olup olmadığını eşzamanlı olarak kontrol etmek için fs.existsSync () yöntemini güvenle kullanabilirsiniz .
path
Modül bir senkron sürümünü sağlamaz path.exists
sen etrafında kandırmak zorunda fs
modülü.
Hayal edebileceğim en hızlı şey fs.realpathSync
, yakalamanız gereken bir hata atacak olanı kullanmaktır , bu nedenle kendi sarmalayıcı işlevinizi bir try / catch ile yapmanız gerekir.
FileSystem (fs) testlerinin kullanılması, daha sonra bir try / catch deyiminde sarmanız gereken hata nesnelerini tetikler. Kendinize biraz çaba sarf edin ve 0.4.x dalında tanıtılan bir özelliği kullanın.
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);
});
});
Üzerindeki belgeler dosyayı değiştirmeyecekseniz fs.stat()
kullanılacağını söylüyor fs.access()
. Bir gerekçe vermedi, daha hızlı veya daha az memeory kullanımı olabilir mi?
Doğrusal otomasyon için düğümü kullanıyorum, bu yüzden dosya varlığını test etmek için kullandığım işlevi paylaştığımı düşündüm.
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;
}
güncellenen asnwer bu insanlar için 'doğru' işaret doğrudan soruya cevap vermez, daha alternatif bir seçenek getirmek.
fs.existsSync('filePath')
burada dokümanlara da bakınız .
Yol varsa true değerini, aksi halde false değerini döndürür.
Zaman uyumsuz bir bağlamda, zaman uyumsuz sürümü await
anahtar kelimeyi kullanarak senkronizasyon yönteminde yazabilirsiniz . Zaman uyumsuz geri arama yöntemini aşağıdaki gibi bir vaat haline getirebilirsiniz:
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');
}
}
erişimdeki dokümanlar ().
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); }, ); }); }
Muhtemelen, eğer bir dosyanın var olup olmadığını bilmek istiyorsanız, dosyaya ihtiyaç duymayı planlıyorsunuzdur.
function getFile(path){
try{
return require(path);
}catch(e){
return false;
}
}
İşte bunun için basit bir sarmalayıcı çözüm:
var fs = require('fs')
function getFileRealPath(s){
try {return fs.realpathSync(s);} catch(e){return false;}
}
Kullanımı:
Misal:
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);
}
Dönüşün yanlış olup olmadığını test etmek için === operatörünü kullandığınızdan emin olun. Fs.realpathSync () 'in uygun çalışma koşulları altında false değerini döndürmesinin mantıklı bir nedeni yoktur, bu yüzden bunun% 100 çalışması gerektiğini düşünüyorum.
Hata ve sonuçta ortaya çıkan performans artışı olmayan bir çözüm görmeyi tercih ederim. API perspektifinden bakıldığında, fs.exists () en şık çözüm gibi görünüyor.
Yanıtlardan, bunun için resmi bir API desteği olmadığı anlaşılmaktadır (doğrudan ve açık bir kontrolde olduğu gibi). Cevapların birçoğu stat kullandığını söylüyor, ancak katı değiller. Örneğin stat tarafından atılan herhangi bir hatanın bir şeyin olmadığı anlamına geldiğini varsayamayız.
Var olmayan bir şeyle denediğimizi varsayalım:
$ 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' }
Var olan bir şeyle deneyelim ama erişimimiz yok:
$ 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' }
En azından isteyeceksiniz:
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;
};
Soru aslında senkronize olmasını istiyorsanız veya sadece senkronize gibi yazılmasını istiyorsanız açık değildir. Bu örnek, yalnızca eşzamanlı olarak yazılması ancak eşzamansız olarak çalışması için await / async kullanır.
Bu, üst düzeyde böyle çağırmanız gerektiği anlamına gelir:
(async () => {
try {
console.log(await dir_exists('god'));
console.log(await dir_exists('fsm/appendage'));
}
catch(e) {
console.log(e);
}
})();
Başka bir seçenek, daha fazla ihtiyacınız varsa, zaman uyumsuz çağrıdan döndürülen vaatte .then ve .catch kullanmaktır.
Bir şeyin var olup olmadığını kontrol etmek istiyorsanız, bunun bir dizin veya dosya gibi doğru türden olmasını sağlamak iyi bir uygulamadır. Bu örnekte yer almaktadır. Bir symlink olmasına izin verilmiyorsa, stat otomatik olarak çapraz bağlantıları geçeceğinden stat yerine lstat kullanmanız gerekir.
Buradaki kodu senkronize etmek için zaman uyumsuzluğun tamamını değiştirebilir ve bunun yerine statSync kullanabilirsiniz. Ancak, eşzamansız ve beklemenin evrensel olarak desteklenmesi durumunda, Eşitleme çağrıları eninde sonunda amortismana tabi olmak için gereksiz hale gelecektir (aksi takdirde, onları async'i gerçekten anlamsız hale getirmek gibi, her yerde ve zincirde tanımlamanız gerekir).