Node.js fs模块原理及常见用途


Posted in Javascript onOctober 22, 2020

JavaScript 的是没有操作文件的能力,但是 Node 是可以做到的,Node 提供了操作文件系统模块,是 Node 中使用非常重要和高频的模块,是绝对要掌握的一个模块系统。

fs 模块提供了非常多的接口,这里主要说一下一些常用的接口。

1.常用API快速复习

fs.stat 检测是文件还是目录

const fs = require('fs')
fs.stat('hello.js', (error,stats)=>{
  if(error) {
    console.log(error)
  } else {
    console.log(stats)
    console.log(`文件:${stats.isFile()}`)
    console.log(`目录:${stats.isDirectory()}`)
  }
})

fs.mkdir 创建目录

const fs = require('fs')
fs.mkdir('logs', error => {
  if(error) {
    console.log(error)
  } else {
    console.log('目录创建成功!')
  }
})

fs.rmdir 删除目录

const fs = require('fs')
fs.rmdir('logs', error => {
  if(error) {
    console.log(error)
  } else {
    console.log('成功删除了目录 logs')
  }
})

fs.writeFile 创建写入文件

const fs = require('fs')
fs.writeFile('logs/hello.log','您好~\n', error => {
  if(error) {
    console.log(error)
  } else {
    console.log('成功写入文件');
  }
})

fs.appendFile 追加文件

const fs = require('fs')
fs.appendFile('logs/hello.log','hello~\n', error => {
  if(error) {
    console.log(error)
  } else {
    console.log('成功写入文件');
  }
})

fs.readFile 读取文件

const fs = require('fs')
fs.readFile('logs/hello.log','utf-8', (error, data) => {
  if(error) {
    console.log(error)
  } else {
    console.log(data);
  }
})

fs.unlink 删除文件

const fs = require('fs')
fs.unlink(`logs/${file}`, error => {
  if(error) {
    console.log(error)
  } else {
    console.log(`成功删除了文件: ${file}`)
  }
})

fs.readdir 读取目录

const fs = require('fs')
fs.readdir('logs', (error, files) => {
  if(error) {
    console.log(error)
  } else {
    console.log(files);
  }
})

fs.rename 重命名,还可以更改文件的存放路径

const fs = require('fs')
fs.rename('js/hello.log', 'js/greeting.log', error => {
  if(error) {
    console.log(error)
  } else {
    console.log('重命名成功')
  }
})

2.第三方npm包 mkdirp 的使用

mkdirp不仅可以创建文件夹,还可以创建多层的文件夹,类似 mkdir -p 命令

midir -p tmp/foo/bar/baz

上述命令也可以在当前目录创建多层几文件夹。

如下代码在当前目录生成多层级文件夹

const mkdirp = require('mkdirp')
mkdirp('tmp/foo/bar/baz').then(made => console.log(`创建目录于: ${made}`))
// 创建目录于: /Users/zhangbing/github/CodeTest/Node/fs/tmp

3.实战举例

实战1

判断服务器上面有没有 upload 目录。如果没有就创建这个目录,如果有的话不做操作

const fs = require('fs')

const path = './upload'
fs.stat(path, (err, data) => {
  if(err) {
    // 执行创建目录
    mkdir(path)
    return
  }
  if(data.isDirectory()) {
    console.log('upload目录存在');
  }else{
    // 首先删除文件,再去执行创建目录
    fs.unlink(path, err => {
      if(!err) {
        mkdir(path)
      }
    })
  }
})

function mkdir(dir) {
  fs.mkdir(dir, err => {
    if(err) {
      console.log(err);
      return
    }
  })
}

实战2

wwwroot 文件夹下面有 images css js 以及 index.html, 找出 wwwroot 目录下面的所有的目录,然后放在一个数组中

使用同步方法方式

const fs = require('fs')
const path = './wwwroot'
const dirArr = []

const dirs = fs.readdirSync(path)
dirs.forEach(item => {
  if(fs.statSync(path + '/' + item).isDirectory()) {
    dirArr.push(item)
  }
})
console.log('dirArr', dirArr)
// dirArr [ 'css', 'images', 'js' ]

使用 async/await 方式

const fs = require('fs')
const path = './wwwroot'
const dirArr = []

function isDir(path) {
  return new Promise((resolve, reject) => {
    fs.stat(path, (error, stats) => {
      if(error) {
        console.log(error)
        reject(error)
        return
      }
      if(stats.isDirectory()) {
        resolve(true)
      } else {
        resolve(false)
      }
    })
  })
}

function main(){
  fs.readdir(path, async (error, data) => {
    if(error) {
      console.log(error)
      return
    } else {
      for(let i = 0; i < data.length; i++) {
        if(await isDir(path + '/' + data[i])) {
          dirArr.push(data[i])
        }
      }
      console.log('dirArr', dirArr)
    }
  })
}

main() // dirArr [ 'css', 'images', 'js' ]

4.管道流

管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。以下实例我们通过读取一个文件内容并将内容写入到另外一个文件中。

const fs = require("fs")
//创建一个可读流
const readerStream = fs.createReadStream('input.txt')
//创建一个可写流
const writerStream = fs.createWriteStream('output.txt')
//管道读写操作
//读取input.txt文件内容,并将内容写入到output.txt文件中
readerStream.pipe(writerStream)
console.log("程序执行完毕")

fs.createReadStream 从文件流中读取数据

const fs = require('fs')
const fileReadStream = fs.fileReadStream('demo1.js')
let count = 0
let str = ''
fileReadStream.on('data', chunk => {
  console.log(`${++count}接收到:${chunk.length}`)
  str += chunk
})
fileReadStream.on('end', () => {
  console.log('---结束---')
  console.log(count + ',' + star)
})
fileReadStream.on('error', error => {
  console.log(error)
})

fs.createWriteStream 写入文件

const fs = require("fs")
const data ='我是从数据库获取的数据,我要保存起来'
//创建一个可以写入的流,写入到文件output.txt中
const writerStream = fs.createWriteStream('output.txt')
//使用utf8编码写入数据
writerStream.write(data,'UTF8')
//标记文件末尾
writerStream.end()
//处理流事件-->finish事件
writerStream.on('finish', () => {
/*finish-所有数据已被写入到底层系统时触发。*/
console.log("写入完成。")
})
writerStream.on('error', err => {
console.log(err.stack);
})
console.log("程序执行完毕")

实战:复制图片

在项目根目录有一张图片2020.png,把它复制到 /wwwroot/images 中

代码如下

const fs = require("fs")

const readStream = fs.createReadStream('./2020.png')
const writeStream = fs.createWriteStream('./wwwroot/images/2021.png')

readStream.pipe(writeStream)

需要特别注意的是,fs.createWriteStream 要写入的目录一定要带上要复制的文件名,也就是不能写成 fs.createWriteStream('./wwwroot/images/') 否则在 macOS 下会报如下错误:

Error: EISDIR: illegal operation on a directory, open <directory>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE8提示Invalid procedure call or argument 异常的解决方法
Sep 30 Javascript
JavaScript实现简单的时钟实例代码
Nov 23 Javascript
JavaScript动态改变表格单元格内容的方法
Mar 30 Javascript
jquery获取文档高度和窗口高度汇总
Jan 25 Javascript
使用BootStrapValidator完成前端输入验证
Sep 28 Javascript
jQuery中Chosen三级联动功能实例代码
Mar 07 Javascript
xmlplus组件设计系列之分隔框(DividedBox)(8)
May 02 Javascript
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
May 30 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
Oct 30 Javascript
express+mockjs实现模拟后台数据发送功能
Jan 07 Javascript
AjaxUpLoad.js实现文件上传功能
Mar 02 Javascript
微信小程序实现点赞、取消点赞功能
Nov 02 Javascript
使用vue构建多页面应用的示例
Oct 22 #Javascript
vue 单页应用和多页应用的优劣
Oct 22 #Javascript
Javascript Symbol原理及使用方法解析
Oct 22 #Javascript
多个Vue项目部署到服务器的步骤记录
Oct 22 #Javascript
针对Vue路由history模式下Nginx后台配置操作
Oct 22 #Javascript
微信小程序基于高德地图API实现天气组件(动态效果)
Oct 22 #Javascript
ES11屡试不爽的新特性,你用上了几个
Oct 21 #Javascript
You might like
PHP通过COM使用ADODB的简单例子
2006/12/31 PHP
实现php加速的eAccelerator dll支持文件打包下载
2007/09/30 PHP
基于php权限分配的实现代码
2013/04/28 PHP
PHP图片处理之使用imagecopyresampled函数实现图片缩放例子
2014/11/19 PHP
php session的锁和并发
2016/01/22 PHP
php微信公众号开发之翻页查询
2018/10/20 PHP
laravel 解决crontab不执行的问题
2019/10/22 PHP
PHP基于进程控制函数实现多线程
2020/12/09 PHP
javascript 延迟加载技术(lazyload)简单实现
2011/01/17 Javascript
JavaScript实现打字效果的方法
2015/07/10 Javascript
关于vue组件事件属性穿透详解
2019/10/28 Javascript
在vue中使用vuex,修改state的值示例
2019/11/08 Javascript
原生js实现自定义难度的扫雷游戏
2021/01/22 Javascript
[02:25]DOTA2英雄基础教程 生死判决瘟疫法师
2013/12/06 DOTA
urllib2自定义opener详解
2014/02/07 Python
python实现数据图表
2017/07/29 Python
Python字典,函数,全局变量代码解析
2017/12/18 Python
python实现图书借阅系统
2019/02/20 Python
python set内置函数的具体使用
2019/07/02 Python
解决python3 安装不了PIL的问题
2019/08/16 Python
python数值基础知识浅析
2019/11/19 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
2020/03/04 Python
python实现爱奇艺登陆密码RSA加密的方法示例详解
2020/05/27 Python
Python 在局部变量域中执行代码
2020/08/07 Python
详解HTML5 canvas绘图基本使用方法
2018/01/29 HTML / CSS
美国知名的摄影器材销售网站:Adorama
2017/02/01 全球购物
波兰电子产品购物网站:Vobis
2019/05/26 全球购物
俄罗斯有趣和原创礼物网上商店:MagicMag
2019/08/01 全球购物
小学竞选班长演讲稿
2014/09/09 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
高三毕业评语
2014/12/31 职场文书
2015教师年度考核评语
2015/03/25 职场文书
软件项目经理岗位职责
2015/04/01 职场文书
2015年小学体育教师工作总结
2015/10/23 职场文书
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python
Vue router配置与使用分析讲解
2022/12/24 Vue.js