fs浅析

245 阅读4分钟

fs用法

//fs file system 文件操作相关
// http服务 读取文件可以使用绝对路径
let fs = require('fs');
let path = require('path'); // join resolve
// 文件的拷贝
fs.readFile(path.resolve(__dirname,'./name.txt'),(err,data)=>{
    fs.writeFile(path.resolve(__dirname,'./name1.txt'),data,(err)=>{
        console.log('写入成功')
    });
}); // __dirname

// 流 边读边写 (可以控制读取的速率)  流基于事件的
// events on / emit ()

发布订阅模式

// let EventEmitter = require('events');
class EventEmitter{
    constructor(){
        this._events = {}
    }
    on(evneName,callback){
        if(this._events[evneName]){
            this._events[evneName].push(callback);
        }else{
            this._events[evneName] = [callback];
        }
    }
    emit(eventName){
        this._events[eventName].forEach(fn => {
            fn();
        });
    }
    off(eventName,callback){
        this._events[eventName] = this._events[eventName].filter((fn)=>{
            return fn != callback
        })
    }
}
let e = new EventEmitter();
// on方法  {'吃饭':[吃米饭]}
let fn = function(){
    console.log('吃米饭')
}
e.on('吃饭',fn)
e.on('吃饭',function(){
    console.log('吃肉')
});
e.off('吃饭',fn)
e.emit('吃饭'); // once newListener

可读流

// 流 几种流 可读流 resquest 可写流 response  双工流  转化流(压缩)
// 可以分段读取 可以控制速率

let fs = require('fs'); // 文件中为了能实现文件的操作 也提供了流相关的api
let path = require('path');
// new ReadStream 返回的是可读流的实例
let rs = fs.createReadStream(path.resolve(__dirname,'name2.txt'),{
    flags:'r', // r w 
    highWaterMark:4, // 64k
    encoding:null,
    autoClose:true, // 读取完毕后 关闭文件吗
    start:0,
    end:5 // slice(start,end) 包含end的
});
// 流 默认流是暂停模式 非流动模式 内部会监控你有没有监听data事件  rs.emit('data',123)
let arr = []; // 异步触发的
rs.on('error',function(err){
    console.log(err);
})
rs.on('data',function(chunk){
    arr.push(chunk);
    console.log(chunk);
    rs.pause(); // 暂停data事件的触发
});
rs.on('end',function(){
    console.log(Buffer.concat(arr).toString()); // 读取完毕
}); 
setTimeout(()=>{
    rs.resume(); // 恢复data事件触发
},1000);


// concat on('data') on('end') Buffer.concat()
// on('error')  resume() pause() 

可写流

let fs = require('fs'); 
let path = require('path');
// 可写流 有两个方法 write() end();

let ws = fs.createWriteStream(path.resolve(__dirname,'name1.txt'),{
    flags:'w', // 文件不存在会创建一个文件 如果有内容会清空内容
    encoding:'utf8',
    highWaterMark: 5,// 每次我预计写入多少个  16k
    autoClose:true,
    start:0
});
// 我们写入的内容必须 是buffer / 字符串
let flag = ws.write(123+'',function(err){
    console.log('写入成功')
}); // 可读流 + 可写流   每次读十个 -》去写入文件 -》先别去读取了
console.log(flag);

// 当我写入完后 在继续写入其他的 on('drain');
// 处理异步 内部创建了空间  [123,'结束']
ws.end('结束');
ws.write(123+''); // write after end 已经结束了 不能在写入了

read+white

let fs = require('fs');
let path = require('path');
// node 的流 是最复杂的
let r = fs.createReadStream(path.resolve(__dirname,'name.txt'),{
    highWaterMark:3
});
let w = fs.createWriteStream(path.resolve(__dirname,'write.txt'),{
    highWaterMark:1,
});
r.pipe(w); // 把可读流 倒入到 可写流中
function pipe(r,w){
    r.on('data',function(data){
        let flag = w.write(data);
        if(!flag) r.pause();
    });
    // 等待写入完成后 恢复读取
    r.on('end',function(){
        console.log('文件读取完毕');
        w.end();
    });  // readFile 可以读取 64k以下的文件 
}; //  fileReader

//  可读流 on(data) on('end') 可写流 write end     pipe
// express + 视频koa

http

// 客户端 浏览器
// 服务端 监听发的请求 监听特定的ip 和 端口 65535

let http = require('http');
let querystring = require('querystring');

// 创建服务端 需要提供一个监听函数 ,这个函数只有当请求到来时触发
// 用的时候不要用3000
// 请求分为三部分 1) 请求行 方法 路径 协议
//              2) 请求头 浏览器信息 + 自定义
//              3) 请求体
// request 可读流 response可写流
// 请求体需要on('data')来接收数据

// 响应也分为三部分   1) 相应行 常见的状态码  200 204 206 范围请求
//                   301 永久重定向 302 临时重定向 304 缓存
//                   401 没权限 403 无法访问 404
//                   500 服务端挂了
//                 2)  响应头  --headers
//                 3) 响应体
// createClinet 爬虫
let server = http.createServer(function(request,response){
    // request中存放的内容
    console.log(request.method); // method 方法名是大写的
    console.log(request.url); // /  端口号 后面的部分 但是没有 hash
    //console.log(request.httpVersion); x
    //console.log(request.headers); // {} 所有的属性名 都是小写的

    // 请求的post方法
    let arr = [];
    request.on('data',function(data){
        arr.push(data);
    });
    request.on('end',function(){ // 不管有没有请求体 都会触发end事件
        // a=b&c=d  => {a:b,c:d}   a=1; b=2
        let str = Buffer.concat(arr).toString();
        // let obj = {};
        // str.replace(/([^=&]*)=([^=&]*)/g,function(){
        //     obj[arguments[1]] = arguments[2]
        // })
        // querystring 用法和 json.parse  json.stringify
        let obj = querystring.parse(str,'&','=');
        response.statusCode = 404; // 写有意义的
        response.setHeader('a','1'); // 设置相应头 设置给客户端的
        response.end(JSON.stringify(obj)); // 立刻把结果响应回去
    });
    // response响应的内容
});
// 双工流
// node写 客户端  -》 node 服务端  ajax
// cookie session
// elementui  iview  文件上传

function uploadFile(){
    axios.post()
}
// server.on('request',function(request,response){
// })
server.listen(3001,'localhost',()=>{
    console.log('3001 starts');
});
// nodemon 只要文件发生变化 就会重新启动服务