1

处理大文件读写 流stream

  • fs.createReadStream

createReadStream 是fs模块里面读流的一个方法

createReadStream 读取文件,有两个参数
第一个参数,读取文件的路径
第二个参数 highWaterMark 最高水位线,默认最多读取64K
读取的类容都是buffer类型
返回的结果是一个可读流的实例,是非流动模式---我们最后要转为流动模式
先要定义一下我们读流的变量,假设我们有一个1.txt文件,我们要读取1.txt里面的类容
我们先设置最高水位线每次读取1k
let rs=fs.createReadStream('./1.txt',{highWaterMark:1})

我们的rs里面有绑定了两个事件方法data和end

  • fs.createWriteStream
const fs = require('fs');
const path = require('path');
let readPath = path.join(__dirname, `./dist/my.txt`);
let copyPath = path.join(__dirname, './dist/my.txt');

// 实现每次读取文件实时写入 将新的buffer存入数组 然后转成buffer
save(`--:第2次加入:--`);
async function save(value) {
    // 读取文件
 const localBufArr = await readFileStream(readPath);
 let totalLength = 0;
//  添加新进入的buffer
 localBufArr.push( new Buffer(value,['utf8']));
 localBufArr.map(v => {
    totalLength += v.length
  })
//   buffer 合并
  let buf =  Buffer.concat(localBufArr, totalLength); // buffer合并 将数组buffer转成整个buffer
  console.log('buf',buf);
//   创建可写流
 let firstCreate = fs.createWriteStream(copyPath);
//  写入buffer
  firstCreate.write(buf);
}

// 读文件 用流
function readFileStream(spath) {
    return new Promise((resolve, reject) => {
    //   判断文件是否存在
        if (fs.existsSync(spath)) {
        let readStream = fs.createReadStream(spath);
        let arr = [];
        let startTime = Date.now();
        // 在内部不断触发rs.emit('data',数据);data不能更改,留动模式开启后,数据会疯狂触发data事件
        readStream.on('data', function (chunk) {  //chunk是buffer类型
          arr.push(chunk)
        })
        // 监听文件读取完毕,会自动触发一次end事件,没有读取完是不会触发的
        readStream.on('end', function (chunk) {
          let useTime = Date.now() - startTime;
          console.log("读文件用" + (useTime/1000) +"s")
          resolve(arr)
        })
        // 监听错误
        readStream.on('error', function (err) {
          console.log(err);
        })
      } else {
        reject("没有改文件")
      }
  
    })
  
  }

甜土豆
425 声望14 粉丝

日拱一卒