fs文件操作模块

  • 官方文档
  • fs模块:用来操作文件的模块,它提供了一系列的方法和属性,用来满足用户对文件的操作需求。

异步操作(基本方法的使用):

代码展示:

  • mkdir目录的创建.js
// nodejs内置模块:fs(文件操作模块) - mkdir(创建目录)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(创建的目录路径(绝对或者相对都可以) , 回调函数)
fs.mkdir('./tx' , (err)=>{
if(err && err.code == 'EEXIST'){
console.log('该文件夹已经存在!!');
}
else{
console.log('文件创建成功! 该文件夹为:' , err);
}
})
  • rename重命名目录.js
// nodejs内置模块:fs(文件操作模块) - rename(重命名目录)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收三个参数(之前的目录路径(绝对或者相对都可以) , 重命名后的路径 , 回调函数)
fs.rename('./tx' , './tx1' , (err)=>{
if(err && err.code == 'EEXIST'){
console.log('该文件夹已经存在!!');
}
else{
console.log('文件重命名成功! 该文件夹为:' , err);
}
})
  • rmdir删除目录.js
// nodejs内置模块:fs(文件操作模块) - rmkdir(删除目录)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(删除的目录路径(绝对或者相对都可以) , 回调函数)
fs.rmdir('./tx1' , (err)=>{
if(err && err.code == 'ENOENT'){
console.log('文件夹不存在!!');
}
else{
console.log('文件删除成功!');
}
})
// 注意: 如果文件夹下面有内容(文件)的话,是无法使用rmdir来删除目录的
  • writeFile创建写入文件.js
// nodejs内置模块:fs(文件操作模块) - writeFile(创建并写入文件)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收三个参数(创建的文件的路径(绝对或者相对都可以) , 写入的内容 , 回调函数)
fs.writeFile('./tx/a.txt' , 'hello! node' , (err)=>{
console.log(err);//输出为null即为没有错误表示成功
})
// 注意: 这个方法的多次调用会覆盖掉原来的内容(新内容覆盖掉旧内容)
  • appendFile创建写入文件.js
// nodejs内置模块:fs(文件操作模块) - appendFile(创建并写入文件)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收三个参数(创建的文件的路径(绝对或者相对都可以) , 写入的内容 , 回调函数)
fs.appendFile('./tx/a.txt' , '你好! 节点' , (err)=>{
console.log(err);//输出为null即为没有错误表示成功
})
// 注意: 这个方法的多次调用不会覆盖掉原来的内容(相较于writeFile)
  • readFile读取文件内容.js
// nodejs内置模块:fs(文件操作模块) - readFile(读取文件)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收三个参数(创建的文件的路径(绝对或者相对都可以) , 读取的格式 , 回调函数)
fs.readFile('./tx/a.txt' , 'utf-8' , (err,data)=>{
if(!err){
console.log(`读取成功,内容为:${data}`);
}
else{
console.log(`读取失败! 错误内容为${err}`);
}
})
  • unlink删除文件.js
// nodejs内置模块:fs(文件操作模块) - unlink(删除文件)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(要删除的文件的路径(绝对或者相对都可以) , 回调函数)
fs.unlink('./tx/a.txt' , (err)=>{
if(!err){
console.log(`文件删除成功!`);
}
else{
console.log(`文件删除失败!! 错误内容为${err}`);
}
})
  • readdir查看目录.js
// nodejs内置模块:fs(文件操作模块) - readdir(查看目录)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(要查看的文件的路径(绝对或者相对都可以) , 回调函数)
fs.readdir('./tx' , (err,data)=>{
if(!err){
console.log(data);//输出常规,查看当前路径下的文件内容
}
else{
console.log(`查看失败!! 错误内容为${err}`);
}
})
  • stat查看路径下的内容详细情况.js
// nodejs内置模块:fs(文件操作模块) - stat(输出详细的目录情况)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(要查看的文件的路径(绝对或者相对都可以) , 回调函数)
fs.stat('./tx' , (err,data)=>{
if(!err){
console.log(data.isDirectory());//判断是否为目录 true
console.log(data.isFile());//判断是否为文件 false
}
else{
console.log(`查看失败!! 错误内容为${err}`);
}
})
// 里面有两个方法是值得我们去了解的:isFile() , isDirectory()

同步操作(基本方法的使用):

  • 所有的方法与异步操作基本一致,只不过是添加了Sync后缀而已

代码展示:(这里就展示一个mkdirSync)

  • mkdirSync创建目录.js
// nodejs内置模块:fs(文件操作模块) - mkdirSync(同步创建目录)

// 1.首先引入模块
const fs = require('fs')

// 2.调用方法
// 该方法接收两个参数(创建的目录路径(绝对或者相对都可以) , 回调函数)
fs.mkdirSync('./tx' , (err)=>{//这是一个同步创建操作,前一步没执行完成会阻塞下一步代码执行
if(err && err.code == 'EEXIST'){
console.log('该文件夹已经存在!!');
}
else{
console.log('文件创建成功! 该文件夹为:' , err);
}
})

fs模块中,提供同步方法是为了方便使用。那我们到底是应该用异步方法还是同步方法呢?

  • 由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一个执行线程。

  • 服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。

这里展示一个小案例:

  • 要求:删除目标目录(但是存在两种情况:若该目录是空目录的话可以直接删除,但是若该目录下存在其他文件的话就无法直接使用rmdir来删除了,必须先是删除该目录下的所有文件,确定该目录为空目录后再执行rmdir删除)

代码展示:

  • 首先是异步和同步的区别
/*
因为fs内置模块中的rmdir方法是无法删除有内容的目录的,因此我们在调用rmdir方法之前
首先要先判断该路径是否有内容,随后清除了该目录下的所有内容,在执行rmdir删除目录
*/

// 1.首先导入fs模块
const fs = require('fs')

// 2.判断要删除的目录下是否存在内容(文件,目录)
fs.readdir('./tx', (err , data)=>{
// 做判断
if(!err){//无错误输出该目录下的内容
// console.log(data);
if(!data){// 3.若没有内容存在
fs.rmdir('./tx',(err)=>{//直接执行目录的删除
console.log(`目录删除成功!`);
})
}
else{// 4.若存在内容
data.forEach(item=>{// 遍历删除文件
fs.unlink(`./tx/${item}`,(err)=>{//异步删除(存在问题)
console.log(`文件删除成功!`);
})

// // 方法1: 使用unlinkSync(不是很推荐,因为node是单线程)
// fs.unlinkSync(`./tx/${item}`,(err)=>{//这里变成unlinkSync即可变成同步删除
// console.log(`文件删除成功!`);
// })
})

fs.rmdir('./tx',(err)=>{//再执行目录的删除
console.log(`目录删除成功!`);
})
}
}
else{
console.log(`发生了错误!错误信息为:${err}`);
}
})
/*
但是这个方法存在缺陷,那就是这是一个异步编程的过程,文件删除的过程与路径删除的过程是分开的
也就是说,当文件删除的过程过长时,目录的删除过程是不受影响的,这样就会导致错误的产生: 即
该目录下的文件还没删除干净就执行删除目录,这是会报错的,因此我们应该将这个异步编程过程转变成
同步编程过程,即先删除了该目录下的文件,再删除该目录,这样就不会有报错了!!
*/

结果展示:

  • 异步删除的结果展示:
    image

  • 同步删除的结果展示:
    image

使用promise嵌套异步解决方案(推荐使用)

//首先以promise的形式导入模块
const fs = require("fs").promises

// 原理版(forEach不改变原数组,使用map能改变原数组更方便)
// fs.readdir("./tx").then(async (data)=>{
// // console.log(data)
// let arr = []
// data.forEach(item=>{
// arr.push(fs.unlink(`./tx/${item}`))
// })
// //Promise.all([])

// await Promise.all(arr)
// await fs.rmdir("./tx")
// })

// 使用promise来解决异步编程(超级简洁版)
fs.readdir("./tx").then(async (data)=>{
await Promise.all(data.map(item=>fs.unlink(`./tx/${item}`)))//使用映射
await fs.rmdir("./tx")
})

结果展示:

image