Node.js fs模块详解:文件权限、读写、目录操作与路径处理
本文详细介绍Node.js中fs文件系统模块的核心功能,涵盖文件权限检测、状态获取、追加读写、基础读写、重命名删除、目录创建与递归处理以及绝对路径获取。通过同步与异步两种模式的代码示例,展示如何高效进行文件I/O操作,帮助开发者掌握Node.js文件处理的最佳实践。
Node.js fs模块概述
fs文件系统模块是Node.js中处理文件操作的核心模块,几乎所有文件相关的功能都依赖于它。该模块提供的API均包含同步和异步两种实现方式,下文将逐一介绍其具体用法。
文件权限检测
1、检测当前进程对文件的权限
使用fs.access(path[, mode], callback)方法可以检查调用进程对指定路径的访问权限。mode参数为整数,支持以下常量值:
- fs.constants.F_OK:表示路径对调用进程可见,即文件存在。
- fs.constants.R_OK:表示路径对应的文件可读。
- fs.constants.W_OK:表示路径对应的文件可写。
- fs.constants.X_OK:表示路径对应的文件可执行。
具体调用方式如下所示:
fs.access('./note.txt',fs.constants.F_OK,(err)=>{
console.log(err?'文件不存在':'文件已经存在');
});
同步版本在发生异常时会直接抛出错误,否则无返回值。由于同步方法会阻塞线程,建议结合try...catch语句使用,适用于所有同步API,示例如下:
try{
fs.accessSync('./note.txt',fs.constants.F_OK);
}catch(ex){
console.log('文件不存在');
}
获取文件状态
2、获取文件状态
通过fs.stat(path, callback)和fs.statSync(path)方法可以获取指定path的文件状态信息。回调函数包含(err, stats)两个参数,其中stats为fs.Stats对象,具备以下属性:
{ dev: 638212,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: undefined,
ino: 105553116266564850,
size: 1094,
blocks: undefined,
atime: 2016-11-22T08:45:43.505Z,
mtime: 2016-11-22T09:33:13.535Z,
ctime: 2016-11-22T09:33:13.535Z,
birthtime: 2016-11-22T08:45:43.505Z }
此外,stats对象还提供以下判断方法:
stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (only valid with fs.lstat())
stats.isFIFO()
stats.isSocket()
具体使用示例如下:
fs.stat('./app.js',(err,stats)=>{
if(err) throw err;
console.log(stats);
});
var stats = fs.statSync('../test.txt');//同步版本
文件追加操作
3、文件追加
使用fs.appendFile(file, data[, options], callback)方法向file写入数据。若文件不存在则自动创建。data参数为字符串或Buffer,options为可选参数(对象或字符串),包含以下属性:
- encoding:默认值为'utf8',指定编码格式。
- mode:默认值为0o666,指定文件打开权限模式。
- flag:默认值为'a',指定文件打开标志。
具体使用示例如下:
fs.appendFile('./test.txt','hello world!\r\n',(err)=>{
if(err) throw err;
console.log('写入成功');
});
//appendFile同步版本,返回值为undefined
fs.appendFileSync('./test.txt','hello nodejs!\r\n');
文件读取与写入
4、文件读取和写入
文件读取使用fs.readFile(file[, options], callback)方法,各参数含义如下:
- file:文件名或文件描述符。
- options:对象或字符串。若为对象,包含encoding(默认null)和flag(默认'r')。
- callback:回调函数,参数为(err, data)。
若指定文件不存在,将直接抛出错误。具体使用示例如下:
fs.readFile('./test4.txt',{encoding:'utf8',flag:'r'},(err,data)=>{
if(err) throw err;
console.log(data);
});
var data = fs.readFileSync('../test4.txt',{encoding:'utf8',flag:'r'});
文件写入数据使用fs.writeFile(file, data[, options], callback)方法,各参数含义如下:
- file:文件名或文件描述符。
- data:字符串或Buffer对象。
- options:对象或字符串。若为对象,包含encoding(默认'utf8')、mode(默认0o666)和flag(默认'w')。
- callback:回调函数,参数为err。
若文件不存在则创建新文件;若存在则覆盖原文件内容。具体使用示例如下:
var data = "hello node!";
fs.writeFile('./test1.txt',data,{flag:'w'},(err)=>{
if(err) throw err;
console.log('written ok.');
});
fs.writeFileSync('./test1.txt',data,{flag:'w'});
此外,也可以利用fs的open、read、write、stat等方法组合实现文件的读取与写入操作。
fs.open(path, flags[, mode], callback)方法用于打开文件并获取文件句柄,flags参数支持以下值:
- 'r':以只读方式打开文件,若文件不存在则报错。
- 'r+':以读写方式打开文件,若文件不存在则报错。
- 'rs+':在同步模式下,以读写方式打开文件。
- 'w':以写方式打开文件,若文件不存在则创建。
- 'wx':以写方式打开文件,若文件不存在则抛出异常。
- 'w+':以读写方式打开文件,若文件不存在则创建;若存在则清空文件内容。
- 'wx+':以读写方式打开文件,若文件不存在则抛出异常。
- 'a':以追加方式打开文件,若文件不存在则创建。
- 'ax':以追加方式打开文件,若文件不存在则抛出异常。
- 'a+':以追加和读方式打开文件,若文件不存在则创建。
- 'ax+':以追加和读方式打开文件,若文件不存在则失败。
回调函数包含(err, fd)两个参数。
fs.read(fd, buffer, offset, length, position, callback)方法用于从文件中读取数据并存入Buffer,各参数含义如下:
- buffer:Buffer对象,用于存储读取的数据。
- offset:Buffer中开始写入的位置。
- length:需要读取的字节长度。
- position:指定从文件的哪个位置开始读取;若设置为null,则从文件当前位置开始读取。
- callback:包含三个参数(err, bytesRead, buffer),其中bytesRead为实际读取的字节数。
fs.write(fd, buffer, offset, length[, position], callback)方法用于将Buffer数据写入指定文件,各参数含义如下:- offset和length指定Buffer中参与写入的部分。
- position:指定文件中的开始写入位置;若不为数字,则从文件当前位置开始写入。
下面是一个使用open、write、read、stat方法实现文件内容复制的函数示例:
function copy(src, dest) {
const destFd = fs.openSync(dest, 'w+'),
srcStat = fs.statSync(src);
const buffer = new Buffer(srcStat.size);
console.log('复制开始...');
console.log(src+'大小:'+srcStat.size)
fs.open(src,'r',(err,fd)=>{
if(err) throw err;
fs.read(fd,buffer,0,srcStat.size,null,(err,bytesRead,buff)=>{
if(err) throw err;
console.log('实际读取大小:'+bytesRead);
fs.close(fd,()=>{});
fs.write(destFd,buff,0,bytesRead,null,(err, written, buffer)=>{
if(err) throw err;
console.log('已完成复制,向'+dest+'写入了'+written);
fs.close(destFd,()=>{});
});
});
});
}
copy('./app.js','./appbak.js');
执行结果如下:
E:\\developmentdocument\\nodejsdemo>node fs-examples.js 复制开始... ./app.js大小:1094 实际读取大小:1094 已完成复制,向./appbak.js写入了1094
文件重命名与删除
5、文件重命名、删除
方法fs.rename(oldPath, newPath, callback)可实现文件重命名或移动。若oldPath与newPath位于同一目录,则为重命名;否则为移动并重命名。具体使用如下:
fs.rename('../test4.txt','./test4.txt',(err)=>{
if(err) throw err;
console.log('rename success.');
});
fs.renameSync('../test2.txt','../test4.txt');
文件删除需使用fs.unlink(path, callback)方法,用法简单,示例如下:
fs.unlink('./dir/11.txt',(err)=>{
if(err) throw err;
console.log('delete file success.');
});
fs.unlinkSync('./dir/11.txt');
目录创建、扫描与删除
6、创建、读取、删除目录
创建目录使用fs.mkdir(path[, mode], callback)方法,mode参数默认为0o777。但该方法仅能创建一级目录,否则抛出异常,示例如下:
fs.mkdir('./a',0o777,(err)=>{
if(err) throw err;
console.log('mkdir success');
});
//mkdir的同步版本,返回值为undefined
fs.mkdirSync('./test',0o777);
为实现多级目录创建,可结合path模块的dirname方法自定义函数,示例如下:
function isFileExists(filePath){
var bool = !0;
try{
fs.accessSync(filePath,fs.F_OK);
}catch(err){
bool = !1;
}
return bool;
}
function mkdirp(dirpath,mode,cb){
if(isFileExists(dirpath)){
cb(dirpath);
}else{
mkdirp(path.dirname(dirpath),mode,function(){
fs.mkdir(dirpath,mode,cb);
});
}
}
扫描目录需使用fs.readdir(path[, options], callback)方法,options参数为字符串或对象,回调函数包含(err, files)两个参数,files为文件名数组。该方法同样仅支持扫描一级目录,示例如下:
fs.readdir('./',(err,files)=>{
if(err) throw err;
console.log(files);
});
若需实现递归扫描目录,可自定义函数,示例如下:
function scandir(dirpath){
var filesArr = {};
if(!isFileExists(dirpath)) return !1;
function scan(filepath){
var statObj = fs.statSync(filepath);
if(!statObj.isDirectory()) return filesArr.push(filepath);
var files = fs.readdirSync(filepath);
files.forEach((file,idx,arr)=>{
scan(filepath+'/'+file);
});
}
scan(dirpath);
return filesArr;
}
删除目录使用fs.rmdir(path, callback)方法,仅能删除一级目录且目录必须为空,示例如下:
fs.rmdir('./dir',(err)=>{
if(err) throw err;
console.log('delete dir success.');
});
若要实现类似rm -rf的递归删除效果,可使用如下代码:
function deldirs(dirpath){
var stat = null,
emptyFoldersArr = [];
function scan(spath){
var files = fs.readdirSync(spath);
emptyFoldersArr.push(spath);
if(files.length>0){
files.forEach((file,idx,arr)=>{
if(fs.statSync(spath+'/'+file).isDirectory()){
scan(spath+'/'+file);
}else{
return fs.unlinkSync(spath+'/'+file),!0;
}
});
}
}
scan(dirpath);
for(var l=emptyFoldersArr.length-1,i=l;i>=0;i--){
fs.rmdirSync(emptyFoldersArr[i]);
}
}
获取绝对路径
7、获取路径的绝对路径
使用fs.realpath(path[, options], callback)方法可获取path的绝对路径,回调函数包含(err, resolvedPath)两个参数,示例如下:
fs.realpath('./test.txt',(err,resolvePath)=>{
if(err) throw err;
console.log(resolvePath);
});
console.log(fs.realpathSync('./test.txt'));
执行结果如下所示:
E:\\developmentdocument\\nodejsdemo>node fs-examples.js E:\\developmentdocument\\nodejsdemo\\test.txt
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
Java和JavaScript的应用场景分工:后端企业级开发与Web前端交互
2026-11-05 15:57:34
除了浏览器和Node.js,还有哪些轻量级Js脚本运行工具?
2026-11-04 17:38:24
无需后端:用JavaScript实现简单网站的本地数据存储
2026-11-03 23:03:30
Node.js 下载慢或官网打不开怎么办
2026-11-03 18:19:37
JS解析大体积Excel文件内存溢出怎么办
2026-11-03 18:19:37
