1. fs
模块
fs
全称为file system
,称之为 文件系统 ,是Node.js
中的 内置模块 ,可以对计算机中的磁盘进行操
作。
1. 文件写入
文件写入就是将 数据 保存到 文件 中,我们可以使用如下几个方法来实现该效果
|方法|说明|
|-|-|
|writeFile
|异步写入|
|writeFileSync
|同步写入|
|appendFile/appendFileSync
|追加写入|
|createWriteStream
|流式写入|
1.1 writeFile
异步写入
- 语法:
fs.writeFile(file, data[, options], callback)
- 参数说明:
file
: 文件名data
: 待写入的数据option
: 选项配置encoding <string> | <null>
默认值:'utf8'
mode <integer>
默认值:0o666
flag <string>
默认值:'w'
。'a'
:打开文件进行追加。如果文件不存在,则创建该文件。'a+'
:打开文件进行读取和追加。如果文件不存在,则创建该文件。'r'
:打开文件进行读取。如果文件不存在,则会发生异常。'w'
:打开文件进行写入。创建(如果它不存在)或截断(如果它存在)该文件。'w+'
:打开文件进行读写。创建(如果它不存在)或截断(如果它存在)该文件。- …
flush <boolean>
如果所有数据都成功写入文件,并且flush
是true
,则使用filehandle.sync()
来刷新数据。默认值:false
。signal <AbortSignal>
允许中止正在进行的写入文件
callback
: 写入回调
- 返回值:
undefined
- 代码示例:
// 1. 导入fs模块
// require 是 Node.js 环境中的'全局'变量,用来导入模块
const fs = require('fs')// 2. 写入文件
// 文件不存在,会自动创建
fs.writeFile('./文件写入.txt', '三人行,必有我师焉', err => {// err写入失败:错误对象 写入成功: nullif(err){console.log('写入失败')return}console.log('写入成功')
})
1.2 writeFileSync
同步写入
- 语法:
fs.writeFileSync(file, data[, options])
参数与
fs.writeFile
大体一致,只是没有callback
参数
- 返回值:
undefined
- 代码示例:
try{fs.writeFileSync('./座右铭.txt', '三人行,必有我师焉。');
}catch(e){console.log(e);
}
Node.js
中的磁盘操作是由其他 线程 完成的,结果的处理有两种模式:
- 同步处理
J
avaScript` 主线程 会等待 其他线程的执行结果,然后再继续执行主线程的代码,
效率较低- 异步处理
JavaScript
主线程 不会等待 其他线程的执行结果,直接执行后续的主线程代码,
效率较好
1.3 appendFile/appendFileSync
追加写入
appendFile
作用是在文件尾部追加内容,appendFile
语法与writeFile
语法完全相同
语法:
fs.appendFile(file, data[, options], callback)
fs.appendFileSync(file, data[, options])
- 返回值:
undefined
- 示例代码:
let fs = require('fs')// 异步追加
fs.appendFile('./文件写入.txt', '\r\nappend追加的内容', err => {if(err){console.log('appendFile追加失败')return}console.log('appendFile追加成功')
})// 同步追加
fs.appendFileSync('./文件写入.txt', '\r\nappendFileSync追加的内容')// writeFile追加内容
fs.writeFile('./文件写入.txt', '\r\nwriteFile追加的内容',{flag: 'a'}, err => {if(err){console.log('writeFile追加失败')return}console.log('writeFile追加成功')
})
fs.writeFileSync('./文件写入.txt', '\r\nwriteFileSync追加的内容',{flag: 'a'})
1.4 createWriteStream
流式写入
- 语法:
fs.createWriteStream(path[, options])
- 参数说明:
path
: 文件路径options
: 选项配置
- 返回值:
Object
- 代码示例:
// 1. 引入fs模块
const fs = require('fs')
// 2. 创建写入流对象
const ws = fs.createWriteStream('./咏鹅.txt')
// 3. write写入内容
ws.write('鹅鹅鹅\r\n')
ws.write('曲项向天歌\r\n')
ws.write('白毛浮绿水\r\n')
ws.write('红掌拨清波\r\n')// 4. 关闭通道
ws.end()
// ws.close()
程序打开一个文件是需要消耗资源的 ,流式写入可以减少打开关闭文件的次数。
流式写入方式适用于 大文件写入或者频繁写入 的场景,writeFile
适合于 写入频率较低的场景
1.5 写入文件的场景
- 文件写入 在计算机中是一个非常常见的操作,下面的场景都用到了文件写入
- 下载文件
- 安装软件
- 保存程序日志,如
Git
- 编辑器保存文件
- 视频录制
当 需要持久化保存数据 的时候,应该想到 文件写入
2. 文件读取
文件读取顾名思义,就是通过程序从文件中取出其中的数据,我们可以使用如下几种方式:
|方法|说明|
|-|-|
|readFile
|异步读取|
|readFileSync
|同步读取|
|createReadStream
|流式读取|
1.1 readFile
异步读取
- 语法:
fs.readFile(path, [, options], callback)
- 参数说明:
path
: 文件路径options
: 选项配置callback
: 回调函数
- 返回值:
undefined
- 代码示例:
const fs = require('fs')// 异步读取
fs.readFile('./咏鹅.txt', err => {if(err){console.log('读取失败')}console.log('读取成功')
})
1.2 readFileSync
同步读取
- 语法:
fs.readFileSync(path, [, options])
- 参数说明:
path
: 文件路径options
: 选项配置
- 返回值:
string | Buffer
- 代码示例:
// 同步读取
const ds = fs.readFileSync('./咏鹅.txt')
const dsf = fs.readFileSync('./咏鹅.txt', 'utf-8')
console.log(ds.toString(), '-----')
console.log(dsf.toString())
1.3 文件流式读取
- 语法:
fs.createReadStream(path, [, options])
- 参数说明:
path
: 文件路径options
: 选项配置
- 返回值:
Object
- 代码示例:
// 创建读取流读写
const rs = fs.createReadStream('../资料/笑看风云.mp4')// 每次取出64kb, 后执行回调一次
rs.on('data', thunk => {console.log(thunk.length) // 65536 字节 => 64KB
})
// 读取完毕后,调取end回调(可选事件)
rs.on('end', ()=>{console.log('读取完毕')
})
1.4 读取文件应用场景
电脑开机
程序运行
编辑器打开文件
查看图片
播放视频
播放音乐
Git 查看日志
上传文件
查看聊天记录
3. 文件移动与重命名
在
Node.js
中,我们可以使用rename
或renameSync
来移动或重命名 文件或文件夹
rename
不会创建文件目录
- 语法:
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
- 参数说明:
oldPath
: 文件当前路径newPath
: 文件新的路径callback
: 操作后的回调
- 代码示例:
// fs.rename('./咏鹅.txt', './咏鹅-骆宾王.txt', err => {
// if(err){
// console.log('重命名失败')
// }
// console.log('重命名成功')
// })fs.rename('./咏鹅.txt', './资料/咏鹅-骆宾王.txt', err => {if(err){console.log('移动失败')return }console.log('移动成功')
})
4. 文件删除
在
Node.js
中,我们可以使用unlink
或unlinkSync
来删除文件
- 语法:
fs.unlink(path, callback)
fs.unlinkSync(path)
- 参数说明:
path
: 文件操作路径callback
: 操作后的回调
- 代码示例:
// fs.unlink('./文件写入.txt', err => {
// if(err){
// console.log('删除失败')
// return
// }
// console.log('删除成功')
// })fs.rm('./文件写入.txt', err => {if(err){console.log('删除失败')return}console.log('删除成功')
})
5. 文件夹操作
借助
Node.js
的能力,我们可以对文件夹进行 创建 、 读取 、 删除 等操作
|方法|说明|
|-|-|
|mkdir/mkdirSync
|创建文件夹|
|readdir/readdirSync
|读取文件夹|
|rmdir/rmdirSync
、rm/rmSync
|删除文件夹|
1.1 mkdir
创建文件夹
在
Node.js
中,我们可以使用mkdir
或mkdirSync
来创建文件夹
- 语法:
fs.mkdir(path, [, options], callback)
fs.mkdirSync(path, [, options])
- 参数说明:
path
: 文件路径options
: 选项配置recursive
: 是否递归
callback
: 回调函数
- 代码示例:
// 创建目录
fs.mkdir('./html', err => {if(err){console.log('创建失败')return}console.log('创建成功')
})
// 递归创建
fs.mkdir('./a/b/c',{recursive: true}, err=>{if(err){console.log('创建失败')return}console.log('创建成功')
})
1.2 readdir
读取文件夹
在
Node.js
中,我们可以使用readdir
或readdirSync
来读取文件夹
- 语法:
fs.readdir(path, [, options], callback)
fs.readdir(path, [, options])
- 参数说明:
path
: 文件路径options
: 选项配置callback
: 回调函数
- 返回值:
undefined
- 代码示例:
const fs = require('fs')
// 读取目录
fs.readdir('./', (err, data)=>{if(err){console.log('读取失败')/ return}console.log('读取成功', data)
})
1.3 rmdir
删除文件夹(使用.rm
加配置项recursive
)
在
Node.js
中,我们可以使用rmdir
或rmdirSync
(rm
或rmSync
) 来删除文件夹
- 语法:
fs.rmdir(path, [, options], callback)
fs.rmdirSync(path, [, options])
- 参数说明:
path
: 文件路径options
: 选项配置recursive
: 是否递归
callback
: 回调函数
- 代码示例:
const fs = require('fs')
// 删除目录
// fs.rmdir('./html', err => {
fs.rm('./html',{recursive: true}, err => { if(err){console.log('删除失败')return}console.log('删除成功')
})
// 递归删除
// .rmdir 会提示被.rm替代
// fs.rmdir('./a',{recursive: true}, err => {
fs.rm('./a',{recursive: true}, err => { if(err){console.log('删除失败')return}console.log('删除成功')
})
6. 查看资源状态
在
Node.js
中,我们可以使用stat
或statSync
来查看资源的详细信息
- 语法:
fs.stat(path[, options], callback)
fs.statSync(path[, options])
- 参数说明:
path
文件夹路径options
选项配置( 可选 )callback
操作后的回调
- 示例代码:
fs.stat('./文件写入.txt', (err, data) => {if(err){console.log(err)return}console.log(data)console.log(data.isFile())console.log(data.isDirectory())
})
- 结果值对象结构:
size
文件体积birthtime
创建时间mtime
最后修改时间isFile
检测是否为文件isDirectory
检测是否为文件夹
7. 相对路径问题
fs
模块对资源进行操作时,路径的写法有两种:
- 相对路径
./座右铭.txt
当前目录下的座右铭.txt
座右铭.txt
等效于上面的写法../座右铭.txt
当前目录的上一级目录中的座右铭.txt
- 绝对路径
D:/Program Files
windows
系统下的绝对路径/usr/bin
Linux
系统下的绝对路径
相对路径中所谓的 当前目录 ,指的是 命令行的工作目录 ,而并非是文件的所在目录
所以当命令行的工作目录与文件所在目录不一致时,会出现一些 BUG
8. __dirname
__dirname
与 require
类似,都是 Node.js
环境中的’全局’变量
__dirname
保存着 当前文件所在目录的绝对路径 ,可以使用 __dirname
与文件名拼接成绝对路径
代码示例:
console.log(__dirname)
fs.writeFileSync(__dirname + '/文件写入.txt', '三人行,必有我师焉')
使用
fs
模块的时候,尽量使用__dirname
将路径转化为绝对路径,这样可以避免相对路径产生的Bug
9. 案例:文件批量重命名
/*
* 文件名 1 2 3 ... 改成 01 02 03 ...
*/
const fs = require('fs')const dir = fs.readdirSync('./')
dir.forEach(item => {const fileName = item.split('-')let [num, name] = fileNameif(Number(num) < 10){num = '0' + num}const newName = num + '-' + nameconsole.log(newName, 'sss')fs.renameSync(`./${item}`, `./${newName}`)
});
2. path
模块
path
模块提供了 操作路径 的功能,我们将介绍如下几个较为常用的几个API
:
|API
|说明|
|-|-|
|path.resolve
|拼接规范的绝对路径(常用)|
|path.sep
|获取操作系统的路径分隔符|
|path.parse
|解析路径并返回对象|
|path.basename
|获取路径的基础名称|
|path.dirname
|获取路径的目录|
|path.extname
|获取路径的扩展名|
代码示例:
const fs =require('fs')
const path = require('path')// 写入文件
fs.writeFileSync(__dirname+'/index.txt', 'hello')console.log(__dirname+'/index.txt') // D:\Note\node-note\03_path模块/index.txt
// 1. resolve 解决
// 第一个参数一般是绝对路径,后续的参数是相对路径
console.log(path.resolve(__dirname, './index.txt')) //D:\Note\node-note\03_path模块\index.txt
// console.log(path.resolve(__dirname, './index.txt', 'A.HTML')) //D:\Note\node-note\03_path模块\index.txt\A.HTML
// console.log(path.resolve(__dirname, '/index.txt', 'A.HTML')) //D:\index.txt\A.HTML// 2. sep 系统的分隔符
console.log(path.sep) // Windows \ Linux /// 3. parse 解析路径返回对象
// __dirname 返回文件目录的决定路径
console.log(__dirname) //D:\Note\node-note\03_path模块
// __filename 返回文件的决定路径
console.log(__filename) //D:\Note\node-note\03_path模块\path.js
const str = 'D:\\Note\\node-note\\03_path模块\\path.js'
console.log(path.parse(str))
/*{root: 'D:\\',dir: 'D:\\Note\\node-note\\03_path模块',base: 'path.js',ext: '.js',name: 'path'
}*/console.log(path.basename(str)) // 获取基础文件名字
console.log(path.dirname(str)) // 获取目录名
console.log(path.extname(str)) // 获取扩展名