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 相关文章推荐
使Ext的Template可以解析二层的json数据的方法
Dec 22 Javascript
Mootools 1.2教程 选项卡效果(Tabs)
Sep 15 Javascript
javascript中最常用的继承模式 组合继承
Aug 12 Javascript
使用原生js写的一个简单slider
Apr 29 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
May 08 Javascript
一款由jquery实现的整屏切换特效
Sep 15 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 Javascript
JavaScript中的继承之类继承
May 01 Javascript
js读取json文件片段中的数据实例
Mar 09 Javascript
vue2.0 根据状态值进行样式的改变展示方法
Mar 13 Javascript
JS实现读取xml内容并输出到div中的方法示例
Apr 19 Javascript
解决layui表格的表头不滚动的问题
Sep 04 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的正则处理函数总结分析
2008/06/20 PHP
php设计模式 Composite (组合模式)
2011/06/26 PHP
php和数据库结合的一个简单的web实例 代码分析 (php初学者)
2011/07/28 PHP
深入php 正则表达式的学习探讨
2013/06/06 PHP
PHP随机生成唯一HASH值自定义函数
2015/04/20 PHP
Laravel使用Queue队列的技巧汇总
2019/09/02 PHP
JS 建立对象的方法
2007/04/21 Javascript
jquery ajax方式直接提交整个表单核心代码
2013/08/15 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
js实现同一页面多个不同运动效果的方法
2015/04/10 Javascript
JS实现简洁、全兼容的拖动层实例
2015/05/13 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
react-router实现跳转传值的方法示例
2017/05/27 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
基于casperjs和resemble.js实现一个像素对比服务详解
2018/01/10 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
详解.vue文件解析的实现
2018/06/11 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
JavaScript实现的拼图算法分析
2019/02/13 Javascript
jQuery中each和js中forEach的区别分析
2019/02/27 jQuery
JavaScript中的 new 命令
2019/05/22 Javascript
es6 super关键字的理解与应用实例分析
2020/02/15 Javascript
vue实现路由懒加载的3种方法示例
2020/09/01 Javascript
如何在vue-cli中使用css-loader实现css module
2021/01/07 Vue.js
探究Python中isalnum()方法的使用
2015/05/18 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
Python连接mysql方法及常用参数
2020/09/01 Python
解决Python安装cryptography报错问题
2020/09/03 Python
苏格兰领先的多渠道鞋店:Begg Shoes
2019/10/22 全球购物
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
特色蛋糕店创业计划书
2014/01/28 职场文书
大学生先进事迹材料
2014/02/16 职场文书
javascript的setTimeout()使用方法总结
2021/11/20 Javascript