//可写流参数设定
LinkList.js
class Node{ //节点类
constructor(element,next){
this.element = element; //存放的数据
this.next = next;
}
}
//对数据的增删改查
class LinkedList{
constructor(){
this.head = null;//链表的头部 头指针
this.size = 0; //链表的长度 链表的长度
}
add(index,element){
if(arguments.length === 1){
//向后面添加
element = index; //如果只传一个参数 那么传入的参数就是要添加的元素
index = this.size;
}
if(index <0 || index > this.size) throw new Error('越界');
if(index == 0) //在索引为0的位置上插入元素
{
let head = this.head;//老的头部
//设置新头,将老的头变为当前节点的下一个
this.head = new Node(element,head);
}
else
{
//先找到当前索引的上一个
let prevNode = this.getNode(index - 1);
prevNode.next = new Node(element,prevNode.next);//将当前上一个人的next指向新的节点,新的节点的下一个指向上一个人的next
}
this.size++;
}
getNode(index)
{
if(index<0||index>this.size)throw new Error('越界');
let current = this.head;//从头开始找
for(let i=0;i<index;i++){
current = current.next;
}
return current; //不停的向后找,找到索引的位置
}
remove(index){
if(index===0){
let node = this.head;//头部节点
if(!node)return null;
this.head = node.next;
this.size--;
return node;
}
}
}
module.exports = LinkedList;
//queue.js
let LinkedList = require('./LinkList');
class Queue{
constructor(){
this.LinkedList = new LinkedList();
}
offer(element){
this.LinkedList.add(element);
}
poll()
{
return this.LinkedList.remove(0);
}
}
/*
let queue = new Queue();
queue.offer('1');
queue.offer('2');
console.log(queue.poll());
console.log(queue.poll());
C:\Users\dptech\Desktop\test>node queue.js
Node { element: '1', next: Node { element: '2', next: null } }
Node { element: '2', next: null }
*/
module.exports = Queue;
//writestream2.js
const fs = require('fs');
const EventEmitter = require('events');
const Queue = require('./queue');
class WriteStream extends EventEmitter{
constructor(path,options){
super();
this.path = path;
this.flags = options.flags || 'w';
this.autoClose = options.autoClose || true;
this.encoding = options.encoding || 'utf8';
this.start = options.start || 0;
this.mode = options.mode || 0o666;
this.highWaterMark = options.highWaterMark || 16*1024;
this.len = 0;//每次调用write方法,会根据写入的内容的个数累加给len属性(缓存的长度)
this.writing = false;//当前写入数据的时候(是否是正在写入)
this.needDrain = false;//是否需要触发drain事件(触发drain事件)
this.offset = this.start;//写入的偏移量(可变的偏移量)
this.cache = new Queue();//用来缓存多次的写入操作(除了第一次)
//维护当前存入的数据个数
this.open();//默认先打开文件
}
open(){ //open方法是异步的
fs.open(this.path,this.flags,this.mode,(err,fd)=>{
if(err)return this.emit('error',err);
this.fd = fd;
this.emit('open',fd);
})
}
write(chunk,encoding="utf8",cb=()=>{}){
//用户是同步调用的write方法
console.log(chunk,encoding,cb);
/*
C:\Users\dptech\Desktop\test>node writestream1.js
0 utf8 [Function: cb]
*/
//用户的写入操作
}
}
module.exports = WriteStream;
//writestream1.js
//我希望写入10个字节,只占用一个字节的内存
const fs = require('fs');
const path = require('path');
const WriteStream = require('./writestream2');
let ws = new WriteStream(path.resolve(__dirname,'name.txt'),{
highWaterMark:3 //是预期 可以根据这个值来控制写入的速率
});
let index = 0;
function write(){
let flag = true;//标识是否可以写入
while(flag && index < 10){
flag = ws.write(index + '');
index++;
}
if(index == 10)
{
ws.end('!!');//文件的关闭操作, ws.write+ws.close
}
}
write();
ws.on('drain',()=>{
console.log('----------');
write();
})
ws.on('close',()=>{
console.log('close');
});