Node.js - fs模块

176 阅读6分钟

fs (file system 文件系统)

fs模块可以实现与硬盘的交互,例如文件的创建、删除、重命名、移动,还有文件内容的导入、读取,以及文件夹的相关操作

页面引入fs

const fs = require('fs'); 

一、文件写入

文件写入就是将数据保存到文件中,实现方法如下:

方法说明
writeFile/writeFileSync异步写入/同步写入
appendFile/appendFileSync追加写入
createWriteStream流式写入

1-1 writeFile 异步写入

语法
fs. writeFile(file, data[, options], callback)
fs. writeFileSync(file, data[, options])

参数说明

  • file 文件名
  • data 待写入的数据
  • option 选项设置(可选)
    • encoding | 默认: 'utf8'
    • mode 默认: 0o666
    • flag 参看支持文件系统flags.默认: 'w'
  • callback 写入回调

返回值 都是 undefined

fs.writeFile('./我真棒.txt', '今天也是好好学习的一天呢~', err=>{
    // err 写入失败:错误对象,成功:null
    if(err){
        console.log('再来一次~');
        return;
    }
    console.log('哇哦哦~真棒!');
})
fs.writeFileSync('./我真棒.txt', '今天也是好好学习的一天呢'); 

1-2 appendFile/appendFileSync 追加写入

appendFile作用是在文件尾部追加内容,语法同writeFile

语法
fs. appendFile(file, data[, options], callback)
fs. appendFileSync(file, data[, options])

返回值 都是undefined

fs.appendFile('./我真棒.txt', '\r\n辛苦了!', err => {
    if (err) {
        console.log('再来一次~');
        return;
    }
    console.log('哇哦哦~真棒!');
})
    
// writeFile追加数据
fs.writeFile('./我真棒.txt', '辛苦了!~', {flag: 'a'}, err=>{
    if(err){
        console.log('再来一次~');
        return;
    }
    console.log('哇哦哦~真棒!');
})
fs.appendFileSync('./我真棒.txt', '辛苦了!');

1-3 createWriteStream 流式写入

语法 fs. createWriteStream(path[, options])

参数说明

  • path 文路径
  • option 选项设置(可选)

返回值 Object

const ws = fs.createWriteStream('今天吃了啥.txt');
ws.write('一包奥利奥\r\n');
ws.write('一根香蕉\r\n');
ws.write('一个猕猴桃\r\n');
ws.write('三个柿子\r\n');
ws.write('三个饼\r\n');
ws.write('五条小白鲳\r\n');

ws.close();

程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数

流式写入方式适用于大文件写入或者频繁写入的场景,writeFile适合于写入频率较低的场景

1-4 文件写入场景

  • 下载文件
  • 安装软件
  • 保存程序的日志,入git
  • 编辑器保存文件
  • 视频录制

当需要持久化保存数据的时候,应该是想到文件写入

二、文件读取

文件读取,就是通过程序从文件中取出其中的数据,实现方法如下:

方法说明
readFile/readFileSync异步读取/同步读取
createReadStream流式读取

2-1 readFile/readFileSync 异步读取/同步读取

语法
fs.readFile(path[, options], callback)
fs.readFileSync(path[, options])
参数说明

  • path 文件路径
  • option 选项设置(可选)
  • callback 写入回调
    返回值 undefined
fs.readFile('./今天吃了啥.txt', (error, data) => {
    if (error) {
        console.log('妹成功');
        return;
    }
    // data为读取内容。,buffer格式,用toString转换一下
    console.log(data.toString())
})
let data = fs.readFileSync('./今天吃了啥.txt')
console.log(data.toString())

2-2 createReadStream 流式读取

语法 fs. createReadStream(path[, options]) 参数说明

  • path 文路径
  • option 选项设置(可选)
const rs = fs.createReadStream('./今天吃了啥.txt')
// 绑定data事件
rs.on('data', chunk => {
    console.log(chunk); //65536 字节 => 64KB 
});
// end事件 可选
rs.on('end', () => {
    console.log('读完了');
})

2-3 文件读取场景

  • 电脑开机
  • 程序运行
  • 编辑器打开文件
  • 查看图片
  • 播放视频
  • 播放音乐
  • git查看日志
  • 上传文件
  • 查看聊天记录

三、文件移动与重命名

在Node.js中,可以用rename或renameSync来移动或重命名文件或文件夹
语法
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
参数说明

  • oldPath 文件当前路径
  • newPath 文件新路径
  • callback 操作后回调
// 重命名
fs.rename('./今天吃了啥.txt', './今天少吃点.txt', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})
// 移动 + 重命名
fs.rename('./今天少吃点.txt', '../今天吃了啥.txt', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})
fs.renameSync('./今天少吃点.txt', '../今天吃了啥.txt');

四、文件删除

在Node.js中,可以用unlink或nlinkSync来删除文件
语法
fs.unlink(path, callback)
fs.unlinkSync(path)
参数说明

  • path 文件路径
  • callback 写入回调
fs.unlink('./我真棒.txt', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})

<!-- 补充 -->
// rm方法 => node.js 14.4版本引入新方法

fs.rm('./我真棒.txt', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})
fs.unlinkSync('./我真棒.txt');
fs.rmSync('./我真棒.txt');

五、文件夹操作

可以对文件夹进行创建、读取、删除等操作

方法说明
mkdir/mkdirSync创建文件夹
readdir/readdirSync读取文件夹
rmdir/rmdirSync删除文件夹

5-1 mkdir/mkdirSync 创建文件夹

在Node.js中,可以用mkdir或mkdirSync来创建文件夹
语法
mkdir(path[, options], callback)
mkdirSync(path[, options])

参数说明

  • path 文件路径
  • option 选项设置(可选)
    • ecursive 默认: false
    • mode 默认: 0o777
  • callback 写入回调
// mk make制作 dir directory 文件夹
fs.mkdir('./demo', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})

// 递归创建
fs.mkdir('./demo/demo1/demo2', { recursive: true }, err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})

fs.mkdirSync('./demo');

在 Windows 上,在根目录上使用 fs.mkdir() (即使使用递归参数)也会导致错误

5-2 readdir/readdirSync 创建文件夹

在Node.js中,可以用 readdir 或 readdirSync 来读取文件夹
语法
readdir(path[, options], callback)
readdirSync(path[, options])

fs.readdir('../fs', (err, data) => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log(data)
    // 数组形式呈现
    // [ 'demo', 'fs.js', 'fs.md', '今天吃了啥.txt' ]
})
const data = fs.readdirSync('../fs');
console.log(data);

5-3 rmdir/rmdirSync 删除文件夹

在Node.js中,可以用 rmdir 或 rmdirSync 来删除文件夹
语法
rmdir(path[, options], callback)
rmdirSync(path[, options])

// 删除demo2
fs.rmdir('./demo/demo1/demo2', err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})
// 递归删除
fs.rmdir('./demo', { recursive: true }, err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})


<!-- [DEP0147] DeprecationWarning: In future versions of Node.js, fs.rmdir(path, { recursive: true }) will be removed. Use fs.rm(path, { recursive: true }) instead
(Use `node --trace-deprecation ...` to show where the warning was created) -->

// 建议使用rm
fs.rm('./demo', { recursive: true }, err => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log('搞定');
})
fs.rmdirSync('./demo/demo1/demo2');

六、查看资源状态

在Node.js中,可以用 stat 或 statSync 来查看资源的详细信息 语法
stat(path[, options], callback)
statSync(path[, options])
参数说明

  • path 文件夹路径
  • options 选项配置(可选)
  • callback 操作后回调
fs.stat('./今天吃了啥.txt', (err, data) => {
    if (err) {
        console.log('瞅瞅哪错了');
        return;
    }
    console.log(data);
    // isFile 是不是文件
    console.log(data.isFile());
    // isDirectory 是不是文件夹
    console.log(data.isDirectory());
})
const data = fs.statSync('./今天吃了啥.txt');
console.log(data);

七、路径

fs模块对资源进行操作时,路径的写法有两种:

  • 相对路径
    • ./今天吃了啥.txt 当前目录下的今天吃了啥.txt
    • 今天吃了啥.txt 效果同上
    • ../今天吃了啥.txt 当前目录的上一级目录中的今天吃了啥.txt
  • 绝对路径
    • D:/Program Files window系统下的绝对路径
    • /usr/bin Linux系统下的绝对路径

相对路径中所谓的当前目录,指的是命令行的工作目录,而并非是文件的所在目录
所以当命令行的工作目录与文件所在目录不一致时,会出现一些bug

八、__dirname

__dirname 与 require 类似,都是Node.js环境中的变量
__dirname 保存着当前文件所在目录的绝对路径,可以使用 __dirname 与文件名拼接成绝对路径

let data = fs.readFileSync(`${__dirname}/今天吃了啥.txt`);
console.log(data.toString());

使用fs模块的时候,尽量使用__dirname将路径转换为绝对路径,这样可以避免相对路径产生的bug