fs模块下的api一般有三种调用方式:
1、异步回调
2、同步Sync
3、fs/promises下的promise形式
文件操作
1、读文件
读文件时不指定文件编码(utf8),默认读出来的是buffer。
1、异步回调
fs.readFile(filePath,[options],回调函数)
const fs = require('fs')
// 异步读取文件
fs.readFile('./static/a.txt', 'utf8', function (err, data) {
// 读取成功时 err为null
if (!err) {
console.log(data)
}
})
2、同步Sync
readFileSync(path,'utf8')
try {
// 需要try\catch包裹来捕获错误,不然会阻塞执行
let fileData = readFileSync(operationFilePath, 'utf8')
console.log(fileData)
} catch (err) {
console.log(err)
// 在catch可以选择将错误冒泡出去
throw err
}
3、promise的形式
需要从fs/promises下引入readFile方法,这个方法返回promise
// 需要从fs/promises下引入各种方法
const { readFile } = require('fs/promises')
let operationFilePath = './static/a.txt'
async function myReadFile() {
try {
let fileData = await readFile(operationFilePath, 'utf8')
console.log(fileData, '??')
} catch (err) {
console.log(err)
}
}
myReadFile()
2、写文件
fs.writeFile(文件路径,内容,[配置对象],回调函数)
writeFile同样有三种方式,一下为异步回调的形式。
const fs = require('fs')
// 异步写入,这样写入是直接覆盖掉整个文件的内容
fs.writeFile('./static/a.txt', '----写入的内容', function (err) {
if (!err) {
console.log('写入成功')
}
})
读写文件的配置对象说明
写文件的配置对象说明
writeFile的第三个参数是个可选的配置对象,可以省略
这个配置对象有以下三个属性:
1、encoding:写入时的文件编码,默认是“utf8”
2、mode:文件权限
3、flag:指定文件写入的行为。写入时默认是“w”
flag各个值的意义:
w(写文件,不存在就创建,存在就覆盖)、
r(用于读,不存在就报错)、
a(用于内容追加,不存在文件就创建),
这三个带上加号后就表示能都读写了。(所以r+可以用于写文件,但是不存在还是会报错的)
w和a加上x( exclusive )就表示文件存在时会操作失败。
读文件的配置对象说明
readFile的第二个参数是一个可选对象,主要能配置encoding和flag,flag默认是“r”。
如果不配置对象,而是配置字符串,就是指定encoding,比如“utf8”。如果两个都没有则读入的是buffer数据。
3、追加文件
1、使用appendFile或者appendFileSync
const fs = require('fs');
try {
fs.appendFileSync('message.txt', '这是追加的文本。\n');
console.log('文本已被追加到文件。');
} catch (err) {
console.error(err);
}
2、将writeFile 的flag设置为a
3、先readFIle再writeFile
文件状态
fs.stat(filePath,(err,info)=>{]) 来获取文件的状态信息。
同样有三种调用方式,异步回调的使用如下:
const fs = require('fs')
fs.stat('./static/a.txt', function (err, info) {
if (err) {
console.log(err)
return
}
console.log(info.mtime.toLocaleString(), '信息')
// info还能判断是文件还是文件夹
console.log(info.isFile());
console.log(info.isDirectory());
})
Node.js的fs.stat
方法返回一个对象,该对象包含了关于文件或目录的详细信息。以下是一些重要的属性:
-
size
:文件的大小,以字节为单位。 -
mtime
:文件的最后修改时间,是一个Date
对象。 -
ctime
:文件状态的最后更改时间(比如权限或所有权的更改),是一个Date
对象。 -
atime
:文件的最后访问时间,是一个Date
对象。 -
birthtime
:文件的创建时间,是一个Date
对象。 -
isFile()
:如果是文件则返回true
。 -
isDirectory()
:如果是目录则返回true
。 -
isSymbolicLink()
:如果是符号链接则返回true
(只有在使用fs.lstat()
时才有效)。 -
mode
:文件的权限位。
所以在stat中用info.isFile()还能判断是文件还是文件夹
文件夹操作
同样有三种调用方式,以下演示异步回调的形式。
1、创建文件夹
fs.mkdir(dirPath,(err)=>{])
mkdir之前需要确定文件夹不存在,用fs.existsSync(dirPath)进行判断。
const fs = require('fs')
// 创建文件夹
// 需要先同步判断文件夹是否存在
if (!fs.existsSync('./bb')) {
fs.mkdir('./bb', (err) => {
console.log(err)
})
}
2、读文件夹下所有文件
fs.readdir(dirPath,[options],(err,files)=>{})
options设置withFileTypes为true,然后调用file.isDirectory()方法能判断是否为文件夹。
// 遍历文件夹所有文件
function getFiles(path) {
// options需要设置widFileTypes为true
fs.readdir(path, { withFileTypes: true }, (err, files) => {
if (err) {
console.log(err)
return
}
for (let file of files) {
if (file.isDirectory()) {
// 做文件夹路径的拼接
let filePath = Path.resolve(path, file.name)
getFiles(filePath)
} else {
console.log(file.name)
}
}
})
}
getFiles('./static')
3、修改文件夹名
fs.rename(oldDirPath,newDirPath,(err)=>{})
修改文件和文件夹的名字都是这个方法,前提是需要确保其存在,所以使用前要判断是否存在。
if (fs.existsSync('./static/gg')) {
fs.rename('./static/gg', './static/dd', (err) => {
console.log(err)
})
} else {
console.log('文件(夹)不存在')
}
复制文件夹
node本身没有提供复制文件夹的api,但是有复制文件的api【fs.copyFIle(src,dest,(err)=>{})】
以下方法演示拷贝到一个空文件夹的实现,思路为:创建出空文件夹,遍历原文件夹,遇到文件就拷贝,遇到文件夹就递归处理。
具体代码如下:
const src = process.argv[2]
const dest = process.argv[3]
// 将一个文件夹拷贝出一个不存在的文件夹
function copyDir(src, dest) {
try {
// 需要先创建出这个空文件夹
if (!fs.existsSync(dest)) {
let err = fs.mkdirSync(dest)
if (err) {
console.log(err)
}
//读取文件夹,文件就拷贝,文件夹就递归处理
fs.readdir(src, { withFileTypes: true }, (err, files) => {
if (err) {
console.log(err)
return
}
for (let file of files) {
const destPath = Path.resolve(dest, file.name)
const srcPath = Path.resolve(src, file.name)
if (file.isDirectory()) {
// 文件夹,就需要先创建文件夹,再往文件夹中复制文件
copyDir(srcPath, destPath)
continue
}
fs.copyFile(srcPath, destPath, (err) => {
if (err) {
console.log(err)
}
})
}
})
}
} catch (err) {
console.log(err)
}
}
copyDir(src, dest)
END
实际工作中可以用fs-extra这个包,更方便点。