fs模块是Node.js官方提供的,用来操作文件的模块。它提高了一系列的方法和属性,用来满足用户对文件的操作需求。fs模块中,所有的方法分为同步和异步两种实现。有 sync 后缀的方法为同步方法,没有 sync 后缀的方法为异步方法。
打开和关闭文件
var fd=fs.open(path,flags,[mode],callback) //返回一个整型 表示打开的文件对象
fs.close(fd,callback)
在使用fs模块之前,需要先导入该模块
const fs = require('fs')
fs.readFile()方法,用来读取知道文件的内容
fs.writeFile()方法,用来向指定的文件中写入内容
1.fs.readFile()的语法格式
fs.readFile(path[, options], callback)
path(必选参数):字符串类型,表示文件的路径
[options](可选参数):表示以什么编码格式来读取文件,默认是utf8
callback(必选参数):文件读取完成后,通过回调函数拿到读取的结果
// 1. 导入fs模块,来操作文件
const fs = require('fs')
// 2.调用fs.readFile() 方法读取文件
// 参数1:读取文件的存放路径
// 参数2:读取文件时候采用的编码格式,一般默认指定utf8
// 参数3:回调函数,拿到读取失败和成功的结果 err dataStr
fs.readFile('./files/1.txt', 'utf8', function (err, dataStr) {
// 2.1 打印失败的结果
// 如果读取成功,则err的值为null
// 如果读取失败,则err的值为错误对象,dataStr 的值为 undefined
console.log(err)
console.log('_____')
// 2.2打印成功的结果
console.log(dataStr)
})
同步文件读取
fs.readSync(fd, buffer, offset, length, position)
异步文件读取
fs.read(fd, buffer, offset, length, position, callback)
流式文件读取
fs.createReadStream(path[, options])
2.fs.writeFile()的语法格式
fs.writeFile(file, data[, options], callback)
file(必选参数):指定一个文件路径的字符串,表示文件的存放路径
data(必选参数):写入的内容
[options](可选参数):表示以什么编码格式来写入文件,默认是utf8
callback(必选参数):文件写入完成后的回调函数
// 1.导入fs文件系统模块
const fs = require('fs')
// 2.调用fs.writeFile()方法,写入文件的内容
// 参数1:表示文件的存放路径
// 参数2:表示要写入的内容
// 参数3:回调函数
fs.writeFile('./files/3.txt', 'hhhh', function (err) {
// 2.1 如果文件写入成功,则err的值等于null
// 2.2 如果文件写入失败,则err的值等于一个 错误对象
// console.log(err)
if (err) {
return console.log('文件写入失败!' + err.message)
}
console.log('文件写入成功!')
})
注意:重复写入同一个文件,会覆盖上一次的内容
如果想追加写入,将flag设置为‘a’
fs.writeFile('./files/3.txt', '你好', {'flag': 'a'}, function (err) {
console.log(err);
});
flags参数表,表示打开文件的模式
r Open file for reading. An exception occurs if the file does not exist. r+ Open file for reading and writing. An exception occurs if the file does not exist. rs+ Open file for reading and writing in synchronous mode. Instructs the operating system to bypass the local file system cache.
This is primarily useful for opening files on NFS mounts as it allows you to skip the potentially stale local cache. It has a very real impact on I/O performance so don't use this flag unless you need it.
Note that this doesn't turn
fs.open()
into a synchronous blocking call. If that's what you want then you should be usingfs.openSync()
w Open file for writing. The file is created (if it does not exist) or truncated (if it exists). wx Like 'w'
but fails ifpath
exists.w+ Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists). wx+ Like 'w+'
but fails ifpath
exists.a Open file for appending. The file is created if it does not exist. ax Like 'a'
but fails ifpath
exists.a+ Open file for reading and appending. The file is created if it does not exist. ax+ Like 'a+'
but fails ifpath
exists.
关于 mode 文件权限的说明:
在linux中文件的权限会为3种,4-表示可读,2-表示可写,1-表示可执行。它们之间的相互组合形成不同权限。
对于文件,有三个权限分配,1:文件所有者,2:文件所属组,3:其他用户。
同步写入文件
var fd=fs.opneSync(path,flags[,mode])
fs.writeSync(fd,buffer,offset,length[,position])
fs.writeSync(fd,data[,position][,encoding])
fs.closeSync(fd)
- path:指定文件
- flags:指定打开文件的模式
- mode:设置文件的访问模式
- fd:整数,代表文件对象,一般是fs.open()函数的返回值
- data:写入的数据
- buffer:缓冲数据
- offset/length
:
确定从哪个位置开始写入buffer。
异步写入文件
fs.open(path, flags[, mode], callback) //借助callback(err,fd)函数实现异步写入文件
fs.write(fd, buffer, offset, length[, position], callback)
fs.write(fd, data[, position[, encoding]], callback)
fs.close(fd)
流式文件写入
var fileWriteStream=fs.createWriteStream(path[,options])
fileWriteStream.write(data)
fileWriteStream.on("close",handler) //end方法执行后调用
fileWriteStream.end()
3.其他文件系统任务
读取文件信息
fs.stat(path, callback)
const fs = require('fs');
//获取目录详细信息
fs.stat('./a', function (err, stats) {
console.log(stats);
});
//获取文件详细信息
fs.stat('./1.txt', function (err, stats) {
console.log(stats);
});
stats.size 表示文件大小。
stats.atime 表示文件中的数据最后访问时间。
stats.mtime 表示文件中的内容修改最后时间。
stats.ctime 表示文件权限,拥有者,所属组,链接数发生改变时的时间。
stats.birthtime 表示文件创建时间。
列出文件(列出path路径的所有子目录,以数组方式存储)
fs.readdir(path[, options], callback)
const fs = require('fs');
const path = require('path');
//读取目录下所有文件
fs.readdir('./a', function (err, files) {
console.log(files);
});
//递归的读取一个目录所有文件
function readDir(dir) {
fs.stat(dir, function (err, stats) {
if (stats.isDirectory()) {
console.log(dir);
fs.readdir(dir, function (err, files) {
files.map(value => {
let cur = path.join(dir, value);
fs.stat(cur, function (err, stats) {
if (stats.isDirectory()) {
readDir(cur);
} else {
console.log(cur);
}
});
});
});
} else {
console.log(dir);
}
});
}
readDir('./node_modules');
删除文件
fs.unlink(path,callback)
const fs = require('fs');
//删除文件
fs.unlink('./3.txt', function (err) {
console.log(err);
});
截取文件
fs.truncate(path, len, callback) 从文件开始出截取len长度,将其后舍弃
const fs = require('fs');
//截取文件成3个字节
fs.truncate('./b.txt', 3, function (err) {
console.log(err);
});
建立和删除目录
fs.mkdir(path[, mode], callback) //建立
fs.rmdir(path, callback) //删除
const fs = require('fs');
//创建目录,默认情况下不支持递归创建目录
fs.mkdir('./a', function (err) {
console.log(err);
});
//通过设置参数二中的recursive为true,则可以递归创建目录
fs.mkdir('./a/b/c', {'recursive': true}, function (err) {
console.log(err);
});
const fs = require('fs');
//rmdir无法删除非空目录
fs.rmdir('./a', function (err) {
console.log(err);
});
拷贝文件
const fs = require('fs');
//参数一表示源文件
//参数二表示目标文件
//参数三表示拷贝操作的修饰符,默认0
//参数四表示回调函数
fs.copyFile('./1.txt', './2.txt', function (err) {
console.log(err);
});
//同步拷贝文件
fs.copyFileSync('./1.txt', './3.txt');
重命名或移动文件
fs.rename(oldPath, newPath, callback)
const fs = require('fs');
//重命名文件
fs.rename('./1.txt', './b.txt', function (err) {
console.log(err);
});
//移动文件
fs.rename('./2.txt', './a/b/c/2.txt', function (err) {
console.log(err);
});
监视文件或目录的状态改变
fs.watchFile(filename[, options], listener) //options包含peristent(是否持续)和interval(间隔检查)属性
const fs = require('fs');
//监视目录
fs.watchFile('./a', function (curr, prev) {
console.log(curr);
console.log(prev);
if (curr.mtimeMs !== prev.mtimeMs) {
console.log('内容发生的改变');
}
});
4. fs模块 - 路径动态拼接的问题
在使用fs模块操作文件时,如果提供的路径是以./或../开头的相对路径时,很容易出现路径动态拼接的错误问题,因为代码在运行的时候,会以执行node命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方案:在使用fs模块操作文件时,直接提供完整的路径,不要以./或../开头的相对路径,从而防止路径动态拼接的问题
注意:在js里面,\表示转义的意思,所以完整路径应该写为
const fs = require('fs')
fs.readFile('C:\\Users\\Lenovo\\Desktop\\nodejs\\files\\1.txt', 'utf8', function (err, dataStr) {
if (err) {
return console.log('读取文件失败!' + err.message)
}
console.log('读取文件成功!' + dataStr)
})
但该写法移植性差,不利于维护,所以我们使用__dirname(表示当前文件所处的目录)
const fs = require('fs')
fs.readFile(__dirname + '/files/1.txt', 'utf8', function (err, dataStr) {
if (err) {
return console.log('读取文件失败!' + err.message)
}
console.log('读取文件成功!' + dataStr)
})
学习内容来自黑马程序员
知识补充文章参考以下博主: