ฉันจะตรวจสอบการมีอยู่ของไฟล์ได้อย่างไร?
ในเอกสารสำหรับโมดูลมีรายละเอียดของวิธีการที่fs
fs.exists(path, callback)
แต่ที่ฉันเข้าใจมันตรวจสอบการมีอยู่ของไดเรกทอรีเท่านั้น และฉันต้องตรวจสอบไฟล์ !
สิ่งนี้สามารถทำได้?
ฉันจะตรวจสอบการมีอยู่ของไฟล์ได้อย่างไร?
ในเอกสารสำหรับโมดูลมีรายละเอียดของวิธีการที่fs
fs.exists(path, callback)
แต่ที่ฉันเข้าใจมันตรวจสอบการมีอยู่ของไดเรกทอรีเท่านั้น และฉันต้องตรวจสอบไฟล์ !
สิ่งนี้สามารถทำได้?
คำตอบ:
ทำไมไม่ลองเปิดไฟล์ดูล่ะ? 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
เลิกใช้แล้ว
* แก้ไข:
การเปลี่ยนแปลง: else if(err.code == 'ENOENT')
ถึง: else if(err.code === 'ENOENT')
Linter บ่นว่าสองเท่ากับไม่สามเท่ากับ
ใช้ 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);
}
});
fs.exists
งานได้เช่นกัน ฉันมีปัญหากับการอนุญาตของไฟล์
path.exists
จริงเลิกใช้แล้วในความโปรดปรานของfs.exists
fs.exists
และfs.existsSync
เลิกใช้แล้ว วิธีที่ดีที่สุดในการตรวจสอบการมีอยู่ของไฟล์คือfs.stat
ตามตัวอย่างด้านบน
fs.existsSync
จะไม่ถูกคัดค้านอีกต่อไปแม้ว่าจะfs.exists
ยังเป็นอยู่ก็ตาม
วิธีที่ง่ายกว่าในการทำสิ่งนี้พร้อมกัน
if (fs.existsSync('/etc/file')) {
console.log('Found file');
}
API เอกสารระบุว่าexistsSync
ทำงานอย่างไร:
ทดสอบว่ามีเส้นทางที่กำหนดอยู่หรือไม่โดยตรวจสอบกับระบบไฟล์
fs.existsSync(path)
จะเลิกตอนนี้ดูnodejs.org/api/fs.html#fs_fs_existssync_path สำหรับการfs.statSync(path)
แนะนำให้ใช้งานแบบซิงโครนัสดูคำตอบของฉัน
fs.existsSync
เลิกใช้แล้ว แต่ไม่มีอีกต่อไป
แก้ไข:
เนื่องจากโหนดv10.0.0
เราสามารถใช้fs.promises.access(...)
ตัวอย่างรหัส async ที่ตรวจสอบว่ามีไฟล์อยู่หรือไม่:
async function checkFileExists(file) {
return fs.promises.access(file, fs.constants.F_OK)
.then(() => true)
.catch(() => false)
}
ทางเลือกสำหรับ stat อาจใช้ใหม่fs.access(...)
:
ฟังก์ชันย่อขนาดย่อสำหรับการตรวจสอบ:
s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
ตัวอย่างการใช้งาน:
let checkFileExists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
checkFileExists("Some File Location")
.then(bool => console.log(´file exists: ${bool}´))
ขยายสัญญาทาง:
// 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);
});
});
}
หรือถ้าคุณต้องการที่จะทำมันพร้อมกัน:
function checkFileExistsSync(filepath){
let flag = true;
try{
fs.accessSync(filepath, fs.constants.F_OK);
}catch(e){
flag = false;
}
return flag;
}
fs.constants.F_OK
ฯลฯ นอกจากนี้ยังเป็นไปได้ที่จะเข้าถึงพวกเขาเช่นfs.F_OK
? แปลก. ยังสั้นซึ่งเป็นสิ่งที่ดี
fs.promises.access(path, fs.constants.F_OK);
เพื่อให้มันเป็นสัญญาแทนการสร้างสัญญา
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
ในการทดสอบการมีอยู่ของไฟล์หนึ่งสามารถใช้เช่น fs.statSync(path)
. fs.Stats
วัตถุจะถูกส่งกลับหากไฟล์ที่มีอยู่ให้ดูhttps://nodejs.org/api/fs.html#fs_class_fs_statsมิฉะนั้นข้อผิดพลาดจะถูกโยนทิ้งซึ่งจะ catched โดยลอง / คำสั่งจับ
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.");
}
fs
ตัวแปรมาจากไหน
fs.existsSync()
ไม่เลิกใช้แล้ว
เวอร์ชันเก่าก่อน V6: นี่คือเอกสาร
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: เอกสารสำหรับfs.stat
fs.stat('/etc/passwd', function(err, stat) {
if(err == null) {
//Exist
} else if(err.code == 'ENOENT') {
// NO exist
}
});
fs.exists
และfs.existsSync
เลิกใช้ตามลิงก์ที่คุณแบ่งปัน
existsSync
ไม่ได้เลิกใช้ตามเอกสารนั้นอาจเป็นเมื่อคุณอ่าน
async / ทางรอทันสมัย (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();
เราจำเป็นต้องใช้fs.stat() or fs.access()
เพราะfs.exists(path, callback)
ตอนนี้เลิกใช้แล้ว
อีกวิธีที่ดีคือเอฟเอสพิเศษ
@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.'
);
}
PS ลองใช้ fs-extra ถ้าคุณยังไม่ได้ใช้มันมันช่างน่ารัก https://github.com/jprichardson/node-fs-extra )
มีความคิดเห็นที่ไม่ถูกต้องจำนวนมากเกี่ยวกับfs.existsSync()
การถูกปฏิเสธ มันไม่ใช่.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
โปรดทราบว่า fs.exists () เลิกใช้แล้ว แต่ fs.existsSync () ไม่ใช่
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);
}
});
});
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);
}
});
หลังจากการทดลองเล็กน้อยฉันพบว่าตัวอย่างต่อไปนี้ใช้fs.stat
เป็นวิธีที่ดีในการตรวจสอบแบบอะซิงโครนัสว่ามีไฟล์อยู่หรือไม่ นอกจากนี้ยังตรวจสอบว่า "ไฟล์" ของคุณเป็น "จริงๆ -is-a-file" (และไม่ใช่ไดเรกทอรี)
วิธีนี้ใช้สัญญาโดยสมมติว่าคุณกำลังทำงานกับรหัสฐานแบบอะซิงโครนัส:
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
เป็นข้อผิดพลาด
ฉันทำอย่างนี้ตามที่เห็นใน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');
}
});
มีปัญหากับเรื่องนี้ไหม?
ในวันก่อนที่จะนั่งลงฉันมักจะตรวจสอบว่ามีเก้าอี้อยู่หรือไม่ฉันนั่งที่อื่นฉันมีแผนสำรองเช่นนั่งบนรถโค้ช ตอนนี้เว็บไซต์ 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
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.
}
เอกสารบอกว่าคุณควรจะใช้access()
แทนสำหรับการเลิกใช้exists()
function fileExists(path, cb){
return new Promise((accept,deny) =>
fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
);
}
var fs = require('fs-extra')
await fs.pathExists(filepath)
อย่างที่คุณเห็นง่ายกว่ามาก และข้อดีเหนือคำสัญญาคือคุณมีการพิมพ์ที่สมบูรณ์ด้วยแพคเกจนี้ (Intellisense / typescript สมบูรณ์)! กรณีส่วนใหญ่คุณจะรวมไลบรารีนี้แล้วเนื่องจาก (+ -10.000) ไลบรารีอื่น ๆ ขึ้นอยู่กับมัน
คุณสามารถใช้fs.stat
เพื่อตรวจสอบว่าเป้าหมายเป็นไฟล์หรือไดเรกทอรีและคุณสามารถใช้fs.access
เพื่อตรวจสอบว่าคุณสามารถเขียน / อ่าน / เรียกใช้ไฟล์ (จำไว้ว่าให้ใช้path.resolve
เพื่อรับเส้นทางแบบเต็มสำหรับเป้าหมาย)
เอกสารอ้างอิง:
ตัวอย่างเต็มรูปแบบ (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);
}());
สำหรับเวอร์ชั่นอะซิงโครนัส! และด้วยรุ่นสัญญา! นี่เป็นวิธีที่เรียบง่ายสะอาดตา!
try {
await fsPromise.stat(filePath);
/**
* File exists!
*/
// do something
} catch (err) {
if (err.code = 'ENOENT') {
/**
* File not found
*/
} else {
// Another error!
}
}
ตัวอย่างที่เป็นประโยชน์มากขึ้นจากรหัสของฉันเพื่อแสดงให้เห็นได้ดีขึ้น
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
}
};
}
}
ตัวอย่างข้างต้นเป็นเพียงการสาธิต! ฉันสามารถใช้เหตุการณ์ข้อผิดพลาดของสตรีมการอ่านได้! เพื่อตรวจจับข้อผิดพลาดใด ๆ ! และข้ามสองสาย!
fs.access('file', err => err ? 'does not exist' : 'exists')
ดูfs.access