当前位置:首页 > Web开发 > 正文

// 读取完成后关闭文件 encoding: true }); // 内部监听data订阅

2024-03-31 Web开发

标签:

1. 普通文件拷贝

文件拷贝的道理是通过fs.readFile从一个文件读取内容,然后通过fs.writeFile将其写入另一个文件。

readFile会默认将文件内容全部读取到内存中,然后再写入另一个文件。

let fs = require(‘fs‘); //fs即file system let path = require(‘path‘); /* 1. 读取文件使用绝对路径; 2. 读取的内容全部读取到内存中; */ // 异步读取文件 fs.readFile(path.resolve(__dirname, ‘./1.txt‘), (err,data) => { // 写入文件;如果对应路径上文件不存在,会自动创建一个文件 fs.writeFile(path.resolve(__dirname, ‘./2.txt‘), data, (err) => { console.log("写入告成"); }); })

但是这种拷贝文件的方法,适用与文件较小时(小于64k)。当大于64k时,会呈现性能问题。凡是会但愿文件边读边写。

这就需要文件流。

2. 事件模块events

文件流基于事件。

// 手动实现一个events模块 模拟let EventEmitter = require(‘events‘); class EventEmitter{ constructor() { // {eventName: [callback1, callback2],....} this._events = {}; } // 订阅 on(eventName, callback) { if(this._events[eventName]) { this._events[eventName].push(callback); } else { this._events[eventName] = [callback]; } } // 颁布 emit(eventName) { this._events[eventName].forEach(fn => { fn(); }); } // removeListener off(eventName, callback) { this._events[eventName] = this._events[eventName].filter(fn => fn !== callback) } } // 应用 const e = new EventEmitter(); let eatFood = () => { console.log(‘eat food‘); } let eatFruit = () => { console.log(‘eat fruit‘); } e.on(‘eat‘, eatFood); e.on(‘eat‘, eatFruit); e.emit(‘eat‘); /* eat food eat fruit */ e.off(‘eat‘, eatFood); e.emit(‘eat‘); // eat fruit

3. 文件流

fs模块供给了流操纵的API。

流分为四类:可读流、可写流、双工流(可读可写)、转换流(压缩文件)

1. 可读流

可读流的感化:

1. 可以分段读取文件 2. 可以控制读取的速率和范畴

可读流主要依赖于fs.createReadStream()要领。 实例订阅on(‘data‘), on(‘end‘)事件。涉及Buffer.concat()要领。

const fs = require(‘fs‘); const path = require(‘path‘); // 相当于创建可读流实例:new ReadStream const rs = fs.createReadStream(path.resolve(__dirname,‘./1.txt‘), { flags: ‘r‘, highWaterMark: 2, //每次最多读取的字节数;默认64k start: 0, end: 10, //[start, end]设置读取范畴 autoClose: true, //读取完成后封锁文件 encoding: true }); // 内部监听data订阅,如果监听到,内部触发rs.emit(‘data‘);然后on的回调函数才执行。是异步操纵。 let arr = [];// 存储二进制代码段 rs.on(‘data‘, function(chunk) { console.log(chunk) arr.push(chunk); rs.pause(); // 暂停读取 }); // 每2秒读取一次 let timer = setInterval(() => { rs.resume(); },2000) // 监听完成事件 rs.on(‘end‘, function() { timer = null; clearInterval(timer); console.log(Buffer.concat(arr).toString()); })

2. 可写流

可写流可以控制每次写入的巨细。主要有write(),end()要领。

const fs = require(‘fs‘); const path = require(‘path‘); let ws = fs.createWriteStream(path.resolve(__dirname, ‘./2.txt‘), { flags: ‘w‘, // 如果文件不存在,则创建;如果已经有内容,,则先清空。 encoding: ‘utf8‘, highWaterMark: 3, // 估量每次写入的字节数;默认16k start: 0, // 起始写入的位置 autoClose: true // 写完后封锁文件 }) // write只能写入字符串或者buffer let flag = ws.write(‘abcdef‘, function(err) { console.log(‘写入告成‘); }); console.log(flag); //写入的长度大于highWaterMark ws.end(‘结束‘); // end要领之后不能再挪用ewrite要领

4 . 文件拷贝 = 可读流+可写流

通过流实现文件拷贝。主要pipe要领。制止全部读取到内存后再写入的情况。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31862.html