node 学习 - fs模块

fs 模块

fs(file system 的缩写,译为“文件系统”)
fs 模块可以实现与硬盘的交互,例如:文件按的创建、删除、重命名、移动,还有文件内容的写入、读取,以及文件夹的相关操作

  1. writeFile 异步写入(文档地址)
/**
 * 需求:
 * 新建一个文件,test.txt, 写入内容:hello world
 */
// 1. 导入 fs 模块
const fs = require('fs')

// 2.写入文件
fs.writeFile('./test.txt','hello world', err =>{
  // 写入完成后调用
  //err 写入失败:错误对象  写入成功:null
  if(err){
    console.log('写入失败');
    return 
  }
  console.log('写入成功')
})

fs 异步和同步

I/O:输入输出
异步写入:writeFile
同步写入:writeFileSync
异步操作效率更高,同步api更容易理解

fs 文件追加写入

appendFile:异步追加
appendFileSync:同步追加

fs.appendFile('./test_3.text','test111',(error) => { 
  if(error){
    console.log('写入失败~~~')
    return
  }
  console.log('写入成功')
 })

fs.appendFileSync('./test_4.text','\r\ntest111')

writeFile也可以实现追加,需要在第三个配置对象中设置flag:'a'

fs.writeFile('./test_4.text','test2222', {
  flag:'a'
}, (error) => {  })

fs 流式写入

createWriteStream 流式写入,相比writeFile,更适合写入频率较高的场合或者大文件的写入

程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数
流式写入方式适用于大文件写入或者频繁写入的场景,writeFile适合于写入频率较低的场景

// 1. 导入fs
const fs = require('fs')

// 2. 创建写入流对象
const ws = fs.createWriteStream('./streamText.txt')

// 3. write
ws.write('test1\r\n')
ws.write('test2\r\n')
ws.write('test3\r\n')
ws.write('test4\r\n')

// 4. 关闭通道
ws.close()

文件写入的应用场景

git add -A 存档,存储到object文件夹下

  1. 下载文件
  2. 安装软件
  3. 保存程序日志,如 git
  4. 编辑器保存文件
  5. 视频录制等

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

fs 文件读取

readFile 异步读取
readFileSync 同步读取

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

// 2. 异步读取
fs.readFile('./streamText.txt', (err, data) => {
  if (err) {
    console.log('err :>> ', err);
    return
  }
  console.log('data :>> ', data.toString());
})

// 3. 同步读取
const dataSync = fs.readFileSync('./streamText.txt')
console.log('dataSync :>> ', dataSync.toString());

// dataSync :>>  
// test1
// test2
// test3
// test4
// data :>>
// test1
// test2
// test3
// test4

读取文件的应用场景

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

fs 模块 - 文件流式读取

createReadStream:会将文件分块读取,每一块为 64kb

// 1. 引入 fs 模块
const fs = require('fs')
// 2. 创建读取流对象
const rs = fs.createReadStream('../myFiles/guidao1.copy.jpg')
// 3. 绑定 data 事件  chunk:块儿 大块儿
rs.on('data', chunk =>{
  console.log('chunk.length :>> ', chunk.length); // 65536 => 64kb
})
// 4. end 可选事件
rs.on('end', ()=>{
  console.log('读取完成')
})

fs 练习 - 复制文件

/**
 * 需求:复制一个文件
 */

const fs = require('fs')
const process = require('process')

// 方法一:readFile
const data = fs.readFileSync('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会.mp4')
// 写入文件
fs.writeFileSync('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会2.mp4',data)
console.log('process.memoryUsage() :>> ', process.memoryUsage());
// 518475776 字节=> 494.45703125 MB

// 方式二:流式操作
// 创建读取流对象
const rs = fs.createReadStream('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会.mp4')
// 创建写入流对象
const ws = fs.createWriteStream('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会3.mp4')
// 绑定 data 事件
rs.on('data', chunk=>{
  ws.write(chunk)
})

rs.on('end', ()=>{
  console.log('process.memoryUsage() :>> ', process.memoryUsage()); 
  //54386688 字节=> 51.8671875 MB
})

// pipe: 中文译为管道
// 将读取流直接交给写入流,简写,使用并不多
// rs.pipe(ws)

readFile 是直接将文件读取写入内存,流式操作则会分块读取
理想状态上流式操作只需要 64kb 的内存,要比 readFile 一次性读取文件节省内存
但是实际上,由于读取速度比写入速度要快,所以流式操作需要更多的内存
实测,在文件并不大的情况下,流式操作占据内存更多,但如果是大文件,流式内存更节省内存

fs 文件重命名与移动

rename: 异步方式,重命名文件名,也可以移动文件,但是**如果文件夹不存在,会移动失败**
renameSync: 同步方式

const fs = require('fs')
fs.rename('../资料/视频.mp4', '../资料/test_视频.mp4', (err) => {
  if (err) {
    console.log('err :>> ', err);
    return
  }
  console.log('重命名成功')
})

fs.renameSync('../资料/test_视频.mp4', '../资料/视频.mp4')

fs 文件删除

unlink
unlinkSync
rm
rmSync

const fs = require('fs')
fs.unlink('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会3.mp4', err=>{
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('删除成功')
})

const unlinkSync = fs.unlinkSync('../myFiles/text2.txt')
console.log('unlinkSync :>> ', unlinkSync);

fs.rm('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会4.mp4',err=>{
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('删除成功')
})

const rmSync = fs.rmSync('../myFiles/text.txt')
console.log('rmSync :>> ', rmSync);

fs 文件夹操作

在vscode的设置中搜索compact,可以设置取消以紧凑形式显示文件夹

  1. 创建 =>mkdir/mkdirSync

mk=> make 制作
dir => directory 文件夹

  • 可以传入3个参数,第二个是可选的配置项,设置 recursive: true 可循环递归创建文件夹
  • 如果重复创建文件夹,会报错,但是配置了 recursive: true 之后就不会了
const fs = require('fs')

fs.mkdir('../makedir/a/b/c', { recursive: true}, err=>{
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('创建成功')
})

const mkdirSync = fs.mkdirSync('../makedir/b/c/d', { recursive: true})
console.log('mkdirSync :>> ', mkdirSync);
  1. 读取 => readdir/readdirSync
const fs = require('fs')
fs.readdir('../myFiles',(err, dirName)=>{
  if (err) {
    console.log('err :>> ', err);
    return
  }
  console.log('dirName :>> ', dirName);  
})

const dirNameArry = fs.readdirSync('../myFiles')
console.log('dirNameArry :>> ', dirNameArry);
  1. 删除 => rmdir/rm/rmSync 建议使用rm
    1. 可以传入3个参数,第二个是可选的配置项,设置 recursive: true 可递归删除文件夹
const fs = require('fs')
fs.rmdir('../makedir/a',{ recursive: true}, err=>{
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('移除成功')
})
fs.rm('../makedir',{ recursive: true}, err=>{
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('移除成功')
})

fs查看资源状态

  1. stat/statSync(status 缩写,译为状态)
    1. 获取的数据(常用)
      1. size 文件大小
      2. birthtime 文件创建时间
      3. atime 最后访问时间
      4. mtime 最后修改时间
      5. ctime 最后一次修改文件状态时间
    2. isFile 是否是文件
    3. isDirectory 是否是文件夹
const fs = require('fs');
fs.stat('../myFiles',(err, data) => { 
  if(err){
    console.log('err :>> ', err);
    return
  }
  console.log('data :>> ', data);
  console.log('data.isFile() :>> ', data.isFile());
  console.log('data.isDirectory() :>> ', data.isDirectory());
 })

fs路径

相对路径

const fs = require('fs');
fs.writeFileSync('./testIndex.html','test')
fs.writeFileSync('testIndex.html','test')
fs.writeFileSync('../testIndex.html','test')

绝对路径

const fs = require('fs');
fs.writeFileSync('D:/testIndex.html','test')
fs.writeFileSync('/testIndex.html','test')

fs相对路径的 Bug

相对路径的参照物:命令行的工作目录
所以相对路径并不稳定
__dirname 保存的是:所在文件的所在目录的绝对路径

const fs = require('fs');
// fs.writeFileSync('testIndex.html','test')
fs.writeFileSync(__dirname + '/testIndex.html','test') // 这种路径拼接写法并不规范,最好使用 path.resolve 包裹一下
//fs.writeFileSync(path.resolve(__dirname + 'testIndex.html','test'))

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