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 相关文章推荐
一个无限级XML绑定跨框架菜单(For IE)
Jan 27 Javascript
javascript 面向对象 function类
May 13 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
Nov 25 Javascript
客户端限制只能上传jpg格式图片的js代码
Dec 09 Javascript
input按钮的事件处理大全
Dec 10 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
简单的ajax连接库分享(不用jquery的ajax)
Jan 19 Javascript
JS实现固定在右下角可展开收缩DIV层的方法
Feb 13 Javascript
浅谈jquery页面初始化的4种方式
Nov 27 Javascript
在vue中添加Echarts图表的基本使用教程
Nov 22 Javascript
vue-cli项目优化方法- 缩短首屏加载时间
Apr 01 Javascript
JavaScript回调函数callback用法解析
Jan 14 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
建立文件交换功能的脚本(二)
2006/10/09 PHP
php jsonp单引号转义
2014/11/23 PHP
PHP常用正则表达式精选(推荐)
2019/05/28 PHP
获取内联和链接中的样式(js代码)
2013/04/11 Javascript
javascript移出节点removeChild()使用介绍
2014/04/03 Javascript
jQuery产品间断向下滚动效果核心代码
2014/05/08 Javascript
JavaScript File API实现文件上传预览
2016/02/02 Javascript
基于jQuery实现仿百度首页选项卡切换效果
2016/05/29 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
js实现碰撞检测特效代码分享
2016/10/16 Javascript
JS获取子、父、兄节点方法小结
2017/08/14 Javascript
Vuex入门到上手教程
2018/06/20 Javascript
微信小程序之onLaunch与onload异步问题详解
2019/03/28 Javascript
vue-cli3使用mock数据的方法分析
2020/03/16 Javascript
[46:00]Ti4 冒泡赛第二轮LGD vs C9 2
2014/07/14 DOTA
在 Django/Flask 开发服务器上使用 HTTPS
2014/07/03 Python
一步步解析Python斗牛游戏的概率
2016/02/12 Python
Python学习小技巧之列表项的排序
2017/05/20 Python
python实现杨辉三角思路
2017/07/14 Python
将TensorFlow的模型网络导出为单个文件的方法
2018/04/23 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
python画环形图的方法
2020/03/25 Python
解决Django部署设置Debug=False时xadmin后台管理系统样式丢失
2020/04/07 Python
解决keras backend 越跑越慢问题
2020/06/18 Python
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
原材料检验岗位职责
2014/03/15 职场文书
节水口号标语
2014/06/19 职场文书
三八节祝酒词
2015/08/11 职场文书
北京大学中文系教授推荐的10本小说
2019/08/08 职场文书
Django一小时写出账号密码管理系统
2021/04/29 Python
Python如何把不同类型数据的json序列化
2021/04/30 Python
Vue+Element UI实现概要小弹窗的全过程
2021/05/30 Vue.js
Nginx实现负载均衡的项目实践
2022/03/18 Servers
Mysql 8.x 创建用户以及授予权限的操作记录
2022/04/18 MySQL
2022年显卡天梯图(6月更新)
2022/06/17 数码科技
python数字图像处理之对比度与亮度调整示例
2022/06/28 Python