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 相关文章推荐
类似框架的js代码
Nov 09 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
Jan 04 Javascript
javascript 回调函数详解
Nov 11 Javascript
JavaScript实现自动消除按钮功能的方法
Aug 05 Javascript
js继承实现方法详解
Dec 16 Javascript
Angular 2.x学习教程之结构指令详解
May 25 Javascript
JS实现微信里判断页面是否被分享成功的方法
Jun 06 Javascript
使用Vue构建可重用的分页组件
Mar 26 Javascript
jQuery中复合选择器简单用法示例
Mar 31 jQuery
angular6.x中ngTemplateOutlet指令的使用示例
Aug 09 Javascript
vue项目接口域名动态获取操作
Aug 13 Javascript
vue 插槽简介及使用示例
Nov 19 Vue.js
使用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之生成GIF动画的实现方法
2013/06/07 PHP
如何给phpcms v9增加类似于phpcms 2008中的关键词表
2013/07/01 PHP
Zend Framework动作助手(Zend_Controller_Action_Helper)用法详解
2016/03/05 PHP
javascript事件模型代码
2007/07/01 Javascript
javascript学习笔记(七) js函数介绍
2012/06/19 Javascript
jQuery实现转动随机数抽奖效果的方法
2015/05/21 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
解析利用javascript如何判断一个数为素数
2016/12/08 Javascript
jquery+html仿翻页相册功能
2016/12/20 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
jQuery制作图片旋转效果
2017/02/02 Javascript
webpack2.0搭建前端项目的教程详解
2017/04/05 Javascript
vue.js的安装方法
2017/05/12 Javascript
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
vue使用mint-ui实现下拉刷新和无限滚动的示例代码
2017/11/06 Javascript
sublime text配置node.js调试(图文教程)
2017/11/23 Javascript
vue 搭建后台系统模块化开发详解
2019/05/01 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
2019/05/27 Javascript
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
python多维数组切片方法
2018/04/13 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
python实现nao机器人手臂动作控制
2019/04/29 Python
解决springboot yml配置 logging.level 报错问题
2020/02/21 Python
python怎么提高计算速度
2020/06/11 Python
Python中三维坐标空间绘制的实现
2020/09/22 Python
HTML5 语音搜索(淘宝店语音搜素)
2013/01/03 HTML / CSS
HTML5 embed 标签使用方法介绍
2013/08/13 HTML / CSS
SQL数据库笔试题
2016/03/08 面试题
如何查询Oracle数据库中已经创建的索引
2013/10/11 面试题
质检的岗位职责
2013/11/17 职场文书
学生安全责任书
2014/04/15 职场文书
毕业实习自我鉴定范文2014
2014/09/26 职场文书
乡镇党员群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
2017元旦晚会开幕词
2016/03/03 职场文书