nodejs学习计划--(二)fs文件系统和path模块

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 | 默认值:'utf8'
      • mode 默认值:0o666
      • flag 默认值:'w'
        • 'a':打开文件进行追加。如果文件不存在,则创建该文件。
        • 'a+':打开文件进行读取和追加。如果文件不存在,则创建该文件。
        • 'r':打开文件进行读取。如果文件不存在,则会发生异常。
        • 'w':打开文件进行写入。创建(如果它不存在)或截断(如果它存在)该文件。
        • 'w+':打开文件进行读写。创建(如果它不存在)或截断(如果它存在)该文件。
      • flush 如果所有数据都成功写入文件,并且 flushtrue,则使用 filehandle.sync() 来刷新数据。默认值:false
      • signal 允许中止正在进行的写入文件
    • callback: 写入回调
  • 返回值:undefined
  • 代码示例:
//  1. 导入fs模块
// require 是 Node.js 环境中的'全局'变量,用来导入模块
const fs = require('fs')

// 2. 写入文件
// 文件不存在,会自动创建
fs.writeFile('./文件写入.txt', '三人行,必有我师焉', err => {
  // err写入失败:错误对象  写入成功: null
  if(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 中的磁盘操作是由其他 线程 完成的,结果的处理有两种模式:

  • 同步处理 JavaScript` 主线程 会等待 其他线程的执行结果,然后再继续执行主线程的代码,
    效率较低
  • 异步处理 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 中,我们可以使用 renamerenameSync 来移动或重命名 文件或文件夹
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 中,我们可以使用 unlinkunlinkSync 来删除文件

  • 语法:
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/rmdirSyncrm/rmSync|删除文件夹|

1.1 mkdir创建文件夹

Node.js 中,我们可以使用 mkdirmkdirSync 来创建文件夹

  • 语法:
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 中,我们可以使用 readdirreaddirSync 来读取文件夹

  • 语法:
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 中,我们可以使用 rmdirrmdirSync(rmrmSync) 来删除文件夹

  • 语法:
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 中,我们可以使用 statstatSync 来查看资源的详细信息

  • 语法:
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

__dirnamerequire 类似,都是 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] = fileName
  if(Number(num) < 10){
    num = '0' + num
  }
  const newName = num + '-' + name
  console.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)) // 获取扩展名

你可能感兴趣的:(#,node学习路程,node.js,学习,前端)