第七十二期:Node中的I/O操作(监听文件变化)

491 阅读2分钟

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

在文件或者目录被添加,删除或者更新时,能够收到消息通知,这个能力对我们来说还是非常重的。

Node的fs模块也提供了这个能力。我们可以试着写一个简单的demo。

监听文件和目录

我们还用原来的项目,安装human-time包,然后创建一个文件,随便写点内容。

npm install --save human-time

然后修改我们的index.js

const fs = require('fs')
const human = require('human-time')
const { exit } = require('process')

const interval = 5007
const file = process.argv[2]
var exists = false

if (!file) {
  console.error('file is not exists!')
  process.exit(1)
}

const created = ({ birthtime }) => {
  return !exists && Date.now() - birthtime < interval
}

const missing = ({ birthtime, mtime, atime, ctime }) => {
  return !(birthtime | mtime | atime | ctime)
}

const updated = (cur, pre) => {
  return cur.mtime !== pre.mtime
}

fs.watchFile(file, { interval }, (cur, pre) => {
  if (missing(cur)) {
    const msg = exists ? 'removed' : "'doesn't exist"
    exists = false
    return console.log(`${file}${msg}`)
  }

  if (created(cur)) {
    exists = true
    return console.log(`${file} created ${human(cur.birthtime)}`)
  }
  exists = true
  if (updated(cur, pre)) {
    return console.log(`${file} updated ${human(cur.birthtime)}`)
  }

  console.log(`${file} modified ${human(cur.birthtime)}`)
})

然后执行:

node index content.js

修改你的content.js

你会发现,终端显示content.js被修改了。

这是怎么回事儿呢

fs模块有两个监听方法。fs.watch 和fs.watchFile。

watch方法可以递归监听整个目录,并且响应速度很快。但是它在不同的平台上可能会存在一些问题。

watchFile方法则以指定的间隔对文件进行轮询。默认5007ms。

文件每次修改时都会调用watchFile方法。watchFile方法接收两个参数,第一个是stats对象,我们可以理解为元信息对象。第二个参数是文件变化之前的元信息对象。

我们使用这些元数据信息以及我们的created , missing和update方法来判断文件的状态,然后输出不同的信息。

用chokidar监听目录变化

fs.watchFile方法速度慢,占用大量CPU,并且之监听单个文件,所以它并不可靠。

chokidar模块包含了核心的监听方法,可配置,且跨平台,并且占有的CPU比较少,而且可以递归监听整个文件目录。

我们安装chokidar 模块,再次修改index.js

npm install --save chokidar

index.js

const chokidar = require('chokidar')
const human = require('human-time')
const watcher = chokidar.watch(process.argv[2] || '.', {
  alwaysStat: true,
})

watcher.on('ready', () => {
  watcher
    .on('add', (file, stat) => {
      console.log(`${file} created ${human(stat.birthtime)}`)
    })
    .on('unlink', (file) => {
      console.log(`${file}:removed`)
    })
    .on('change', (file, stat) => {
      const msg = +stat.ctime === +stat.mtime ? 'updated' : 'modified'
      console.log(`${file}:${msg}:${human(stat.ctime)}`)
    })
    .on('addDir', (dir, stat) => {
      console.log(`${dir} 文件夹created:${human(stat.birthtime)}`)
    })
    .on('unlinkDir', (dir) => {
      console.log(`${dir}:文件夹:removed`)
    })
})

再次执行我们的index.js对文件夹进行监听

node index

修改文件或者进行其他操作,你会得到下面的结果:

非常方便。因为它支持链式调用。

最后

  • 公众号《JavaScript高级程序设计》
  • 公众号内回复”vue-router“ 或 ”router“即可收到 VueRouter源码分析的文档。
  • 回复”vuex“ 或 ”Vuex“即可收到 Vuex 源码分析的文档。

全文完,如果喜欢。

请点赞和"在看"吧,最好也加个"关注",或者分享到朋友圈。