Path路径解析模块、Stream流、EventEmitter事件监听

Path模块

处理文件路径的小工具
引入:

var path = require("path")

1、解析后缀名

path.extname(p)
  1. 返回路径中文件的后缀名,即路径中最后一个’.'之后的部分。如果一个路径中并不包含’.‘或该路径只包含一个’.’> 且这个’.'为路径的第一个字符,则此命令返回空字符串。
  2. 如果在使用之前的mime匹配标准格式则为:
let path = require('path');
let mime = require('./mime.json')
module.exports = () => {
    //1. 解析后缀名
    let pathname = "test.json";
    let pathnamem = "test.jpg";
    let a = path.extname(pathname);
    let b = path.extname(pathnamem);
    console.log(a, b);//.json  .jpg
    let c = mime[a];
    let d = mime[b];
    console.log(c, d);// application/json image/jpeg
}

2、文件名连接

该方法的主要用途在于,会正确使用当前系统的路径分隔符

path.join([path1][, path2][, ...])

示例:

    // 2. join
      let pathname = path.join('public','test','test2');
      console.log(pathname);//   public\test\test2

3、绝对路径

path.resolve([from ...], to)

将 to 参数解析为绝对路径,给定的路径的序列是从右往左被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径。
百度后了解到,join是拼接给定参数形成路径,而resolve类似cd

  let c = path.resolve('/foo/bar', './baz');
    console.log(c); //  D:\foo\bar\baz

    let b = path.resolve('/foo/bar', '/tmp/file/');
    console.log(b);//  D:\tmp\file

  let a = 
  path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
  console.log(a);//  D:\node\Mystudy1\wwwroot\static_files\gif\image.gif

4、basename

	path.basename(p)

返回路径中的最后一部分。

   let a= path.basename("public/zmtTest/addfile");
   console.log(a);//addfile

5、path.parse(pathString)

字符串转对象

 let a= path.parse("public/zmtTest/addfile");
   console.log(a);
   //输出结果如下:
   { root: '',
  dir: 'public/zmtTest',
  base: 'addfile',
  ext: '',
  name: 'addfile' }

Stream流

  1. Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个> Stream,还有stdout(标准输出)。
  2. 所有的 Stream 对象都是 EventEmitter 的实例。
  1. 四种流类型:

Readable - 可读操作。

Writable - 可写操作。

Duplex - 可读可写操作.

Transform - 操作被写入数据,然后读出结果。

  1. 常用的事件有:

data - 当有数据可读时触发。

end - 没有更多的数据可读时触发。

error - 在接收和写入过程中发生错误时触发。

finish - 所有数据已被写入到底层系统时触发。

从流中读取数据示例
  1. 步骤
  • 创建 可读 流
  • 设置编码为 utf8
  • 处理流事件 --> data, end, and error
  1. 文件目录如下:
    在这里插入图片描述
  2. 具体代码:
  • 主文件为app.js文件
const http = require('http');
let server = require('./models/server');

http.createServer(server).listen(8080, "localhost", () => {
    console.log("——————本机端口号: http://127.0.0.1:8080————————");
})
  • cnpm init 创建package.json文件,手动建立node_modules文件夹
  • 新建models目录封装模块,其中,server.js文件同之前一样:
const url = require('url');
let stream=require('./stream')

module.exports = (req, res) => {
    let path = url.parse(req.url);
    if (path.pathname != "/favicon.ico") {
        res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
        //加载其他模块
        stream();

        res.write("首页");
        res.end();
    }
}
  • 再创建数据流模块
//数据流
var fs = require('fs')
module.exports = () => {
    var readerstream = fs.createReadStream("public/stu.txt");
    var data = '';
    readerstream.setEncoding('utf-8');
    // 有数据可读时触发。
    readerstream.on("data", (res) => {
        console.log(data + res);
    });
    //没有更多的数据可读时触发。
    readerstream.on("end", () => {
        console.log(data);
    });
    //在接收和写入过程中发生错误时触发。
    readerstream.on("err", () => {
        console.log("数据读取失败!");
    });

    // finish 所有数据已被写入到底层系统时触发。  写入流调用
    // readerstream.on("finish", () => {
    //     console.log("数据读取完成");
    // });
}
从流中写入数据示例
  1. 步骤

要点一:写入数据设置格式不再是直接setEncoding,而是.write(data,'UTF8');
要点二:标记文件末尾

  • 创建 可写流,写入到文件 out.txt
  • 设置编码为 utf8!!!
  • 标记文件末尾
  • 处理流事件 --> data, end, and error
  1. 具体代码(只更改了读取数据的核心代码)
    var fs = require('fs')
    module.exports = () => {
        var writestream = fs.createWriteStream("public/out.txt");
        var data = '这是一段测试';
        // 使用 utf8 编码写入数据
        writestream.write(data, 'UTF8');
        // 标记文件末尾
        writestream.end();
        // 处理流事件 --> data, end, and error
        writestream.on('finish', () => {
            console.log("写入完成。");
        });

        writestream.on('error', (err) => {
            console.log(err.stack);
        });

        // finish 所有数据已被写入到底层系统时触发。  写入流调用
        writestream.on("finish", () => {
            console.log("数据读取完成");
        });
    }
管道流

管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。
我们把文件比作装水的桶,而水就是文件里的内容,我们用一根管子(pipe)连接两个桶使得水从一个桶流入另一个桶,这样就慢慢的实现了大文件的复制过程。
在这里插入图片描述
管道流示例

    // 管道流  边读边写

    let readstream = fs.createReadStream("public/stu.txt");//创建可读流
    let writestream = fs.createWriteStream("public/data.txt");//创建可写流
    readstream.pipe(writestream);// 读取 stu.txt 文件内容,并将内容写入到 data.txt 文件中

    readstream.on("end", () => {
        console.log("管道流读取数据完成");
    });
    writestream.on("finish", () => {
        console.log("管道流写入数据完成");
    });
非阻塞IO 、阻塞IO

node 里面的非阻塞IO 阻塞IO

   fs.readFile();//异步读取文件
   fs.readFileSync()//同步读取  阻塞IO
回调函数处理异步 (非阻塞)
var fs=require("fs");
阻塞(同步)请求数据  等待请求完成在执行后续代码
var data=fs.readFileSync("mime.json");
console.log(data.toString());

 非阻塞式请求代码  nodejs中多数方法为异步请求方式
fs.readFile("mime.json",function (err,res){
    if(err) throw err;
    console.log(res.toString());
});
console.log(1);

处理异步请求  外边可以获取到请求的数据的方式
//1.使用回调函数来获取数据
function getMime(callback){
    fs.readFile("mime.json",function (err,res){
        if(err) throw err;
        callback(res.toString());
    });
}
console.log(1);
//这样就可以在外部获取异步的数据  也可以暴露出去别的文件使用
module.exports=getMime(function (data){
    console.log(data);
});

Node.js EventEmitter

知识点
  1. Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列
  2. Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 所有这些产生事件的对象都是events.EventEmitter实例
  3. on 函数用于绑定事件函数,emit 属性用于触发一个事件。
使用

在server.js中(文件目录上文中有图)

  1. 引入 events 模块
var events = require('events');
  1. 创建 eventEmitter 对象
let eventemit = new events.EventEmitter();
  1. server.js中 res.end之前执行方法(传递了一个参数----新建的对象)
event(eventemit);
  1. 新建event模块,暴露方法
//事件驱动

module.exports = (eventemit) => {
    //监听事件驱动
    //监听的过程
}
方法

node中,onaddListener没有区别,使用on添加多个事件,后面的事件也不会覆盖之前的事件
EventEmitter.prototype.on = EventEmitter.prototype.addListener;

  1. addListener(event, listener)
    为指定事件添加一个监听器
    在event.js中:
   eventemit.addListener('getjson',()=>{
        console.log('事件json 监听函数执行');
    });

server.js

setTimeout(() => {          
            eventemit.emit("getjson");
        }, 4000);
  1. on(event, listener)
    为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
    在event.js中:
 eventemit.on('getdata', () => {
        console.log('事件一');
    });
    eventemit.on('getdata', () => {
        console.log('事件二');
    });

server.js

eventemit.emit("getdata");//不会覆盖第一次

输出为

事件一
事件二

  1. once(event, listener)
    为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
    event.js中:
  eventemit.once('oncetest', () => {
        console.log('事件oncetest 监听函数执行');
    });

server.js

 setTimeout(() => {          
            eventemit.emit("oncetest");//不执行
        }, 4000);
        eventemit.emit("oncetest");//输出事件oncetest 监听函数执行
  1. removeListener(event, listener)
    移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。

它接受两个参数,第一个是事件名称,第二个是回调函数名称。

    let getdatafun=()=>{
        console.log('事件一');
    }
    eventemit.on('getdata',getdatafun);
    //事件驱动的方法
    eventemit.removeListener('getdata',getdatafun);
  1. removeAllListeners([event])
    移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。
   eventemit.removeAllListeners();
  1. emit(event, [arg1], [arg2], [...])
    按监听器的顺序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

  2. listeners(event)
    返回指定事件的监听器数组。

  let es=eventemit.listeners('getdata');
    console.log(es);//[ [Function: getdatafun] ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值