Skip to content

原生的stream对“行”无能为力,它只是把文件当作一个数据流,简单粗暴地流动。很多文件格式都是分行的,例如csv文件、日志文件等

node.js提供了按行读取API——readline,它本质上也是stream,只不过是以“行”作为数据流动的单位

readline的使用

相比于stream的data和end自定义事件,readline需要监听line和close两个自定义事件。readline的基本使用示例如下:

js
var fs = require('fs')
var path = requrie('path')
var readline = require('readline')

var fileName = path.resolve(__dirname, 'readline-data.txt')
// 创建读取文件的stream对象
var readStream = fs.createReadStream(fileName)
// 创建readline对象
var rl = readline.createInterface({
  // 输入,依赖于stream对象
  input: readStream
})
// 监听逐行读取的内容
rl.on('line', function(lineData) {
  console.log('lineData: ', lineData)
})
// 监听读取完成
rl.on('close', function() {
  console.log('readline end')
})

以上代码,需要先根据文件名,创建读取文件的stream对象,然后传入并生成一个readline对象,然后通过line事件监听逐行读取,通过close事件监听读取完成。

应用场景

对于处理按行为单位的文件,如日志文件,使用readline是最佳选择。下面是一个实际例子,用来记录访问数:

js
var num = 0
// 监听逐行读取的内容
rl.on('line', function(lineData) {
  if (lineData.indexOf('2018-10-30 14:00') >= 0 && lineData.indexOf('user.html') >= 0) {
    num++
  }
})
// 监听读取完成
rl.on('close', function() {
  console.log('num: ', num)
})

最后,将这个示例所用的代码贴到下面,供学习参考:

js
var fs = require('fs')
var path = require('path')
var memeye = require('memeye')
var readline = require('readline')

memeye()

function doReadLine() {
  var fileName = path.resolve(__dirname, 'readline-data.txt')
  var readStream = fs.createReadStream(fileName)
  var rl = readline.createInterface({
    input: readStream
  })

  var num = 0
  rl.on('line', function(lineData) {
    if (lineData.indexOf('2018-10-30 14:00') >= 0 && lineData.indexOf('user.html') >= 0) {
      num++
    }
  })
  // 监听读取完成
  rl.on('close', function() {
    console.log('num: ', num)
  })
}

setTimeout(doReadLine, 5000)

共 20 个模块,1301 篇 Markdown 文档。