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 相关文章推荐
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
May 14 Javascript
jQuery Ajax文件上传(php)
Jun 16 Javascript
js弹窗代码 可以指定弹出间隔
Jul 03 Javascript
js arguments,jcallee caller用法总结
Nov 30 Javascript
JavaScript小技巧整理篇(非常全)
Jan 26 Javascript
基于BootStrap的Metronic框架实现页面链接收藏夹功能按钮移动收藏记录(使用Sortable进行拖动排序)
Aug 29 Javascript
BootStrap实现轮播图效果(收藏)
Dec 30 Javascript
Angular 2.x学习教程之结构指令详解
May 25 Javascript
详解ElementUI之表单验证、数据绑定、路由跳转
Jun 21 Javascript
cordova入门基础教程及使用中遇到的一些问题总结
Nov 14 Javascript
在一个页面实现两个zTree联动的方法
Dec 20 Javascript
QQ跳转支付宝并自动领红包脚本(最新)
Jun 22 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程序中的常见漏洞进行攻击
2006/10/09 PHP
PHP使用正则表达式清除超链接文本
2013/11/12 PHP
javascript js cookie的存储,获取和删除
2007/12/29 Javascript
FLASH 广告之外的链接
2008/12/16 Javascript
JavaScript去掉空格的方法集合
2010/12/28 Javascript
始终在屏幕中间显示Div的代码(css+js)
2011/03/10 Javascript
探讨在JQuery和Js中,如何让ajax执行完后再继续往下执行
2013/07/09 Javascript
js控制iframe的高度/宽度让其自适应内容
2014/04/09 Javascript
JS实现静止元素自动移动示例
2014/04/14 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
分享我的jquery实现下拉菜单心的
2015/11/29 Javascript
jQuery使用cookie与json简单实现购物车功能
2016/04/15 Javascript
jQuery使用each方法与for语句遍历数组示例
2016/06/16 Javascript
关于Javascript中defer和async的区别总结
2016/09/20 Javascript
jquery+ajax实现省市区三级联动效果简单示例
2017/01/04 Javascript
JS异步文件上传(兼容IE8+)
2017/04/02 Javascript
nodejs异步编程基础之回调函数用法分析
2018/12/26 NodeJs
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
CKEditor扩展插件:自动排版功能autoformat插件实现方法详解
2020/02/06 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
[01:21:36]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python过滤函数filter()使用自定义函数过滤序列实例
2014/08/26 Python
Python实现获取命令行输出结果的方法
2017/06/10 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
python如何提升爬虫效率
2020/09/27 Python
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
英国家用电器购物网站:Hughes
2018/02/23 全球购物
安全大检查实施方案
2014/02/22 职场文书
空中乘务员岗位职责
2014/03/08 职场文书
食品安全主题班会
2015/08/13 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
php 获取音视频时长,PHP 利用getid3 获取音频文件时长等数据
2021/04/01 PHP
解决numpy和torch数据类型转化的问题
2021/05/23 Python
html,css,javascript是怎样变成页面的
2023/05/07 HTML / CSS