• Node中流的概念


    在学习node的过程中,对于流的概念一直不是很理解,通过查阅一些资料,现在将自己对流的一些理解进行总结一下。

    一.流的理解

    首先我们必须知道什么是流,很多书中只是提到使用流读写文件怎么怎么方便,却不提流到底是什么?在说流之前我们先说一下流数据
    流数据:就是字节数据,在应用程序中各种对象之间交换与传输数据的时候,总是先将该对象中所包含的数据转化为字节数据也就是流数据。再通过流的传输,到达目的对象后,再将流数据转化为该对象中可以使用的数据。
    从上面可知,流就是用来传输流数据的,它是一种传输手段
    流:在一个应用程序中,流是一组有序的,有起点和终点的字节数据(流数据)的传输手段

    二.能够使用流的对象

    从流的概念中我们可以知道流是用来传输流数据的,也就是说我们需要把其他的对象数据转化为流数据。
    在Node中,使用了各种实现了stream.Readable接口的对象读取流。也就是说只有这些对象才能够读取流
    Node.js中可以读取数据流的对象,列表如下:

    对象 描述
    fs.ReadStream 用于读取文件
    http.IncomingMesage 代表客户端请求或服务端响应
    net.Socket 代表一个socket端口对象
    child.stdout 用于创建子进程的标准输出流
    child.stderr 用于创建子进程的标准错误输出流
    process.stdin 用于创建进程的标准输入流
    Gzip 用于实现数据压缩

    上面这些读取数据的对象将会触发的事件

    事件名 描述
    readable 当可以从流中读取数据时触发
    data 当读取到来自文件,客户端,服务器端等对象的新的数据时触发
    end 代表一个socket端口对象
    child.stdout 当读取完所有的事件时触发,该事件的触发意味着data事件将不再被触发
    err 当读取数据的过程中产生错误时触发
    close 当用于读取数据的对象被关闭时触发,并非所有用于读取流数据的对象都会触发该事件

    上面这些读取数据的对象所拥有的方法
    在对象读取流的过程中,对象还拥有一些方法,可以对流进行一些操作,比如指定编码,指定流的传输目的地等。列表如下:

    方法名 描述
    read 用于读取数据
    setEncoding 用于指定用什么编码方式读取数据
    pause 用于通知对象停止触发data事件
    resume 用于通知对象恢复触发data事件
    pipe 用于设置一个数据通道,然后取出所有流数据并将其输出到通道另一端所指向的目标对象中
    unpipe 用于取消pipe设置的通道

    接下来使用fs模块中的createReadStream方法创建一个将文件读取为流数据的ReadStream对象,介绍一下流数据的读取。示例代码如下:

    const fs = require('fs');
    
    let file = fs.createReadStream('./data.txt');
    // console.log(file);  //得到的是一个ReadStream对象
    //对象在读取文件时,需要先打开文件,打开文件会触发open事件
    file.on('open',function(fd){
      console.log('开始读取文件');
      // console.log(fd);
    });
    //对象触发data事件,读取数据
    file.on('data',function(data){
      console.log('读取到数据');
      console.log(data.toString());
    });
    //读取文件完毕,触发end事件
    file.on('end',function(){
      console.log('文件读取完毕');
    });
    //关闭文件,触发close事件
    file.on('close',function(){
      console.log('关闭文件')
    });
    file.on('error',function(err){
      console.log(err)
    });
    

    上面介绍了Node.js中用于读取流的对象,以及在读取过程中,对象可能触发的事件以及调用的方法。下面介绍Node.js中用于写入流的对象,以及在写入过程中,这些对象可能触发的事件和调用的方法。

    在Node.js中,使用各种实现了stream.Writable接口的对象来将流数据写入到对象中,所有这些对象都是继承了EventEmitter类的实例,在写入数据的过程中,将可能触发各种事件

    各种用于写入流数据的对象,如下表所示:

    对象 描述
    fs.WriteStream 用于写入文件
    http.ClientRequest 用于写入http客户端请求数据
    http.ServerResponse 用于写入http服务端响应数据
    net.Socket 代表一个socket端口对象
    child.stdin 用于创建子进程的标准输入流
    process.stderr 用于创建进程的标准错误输出流
    process.stdout 用于创建进程的标准输出流
    Gunzip 用于解压数据

    这些对象将有可能触发的事件如下表所示:

    事件名 描述
    drain 当用于写入数据的write方法返回false之后触发
    finish 当end方法被调用且数据被全部写入操作系统缓存区时触发
    pipe 当用于读取数据的pipe方法被调用时触发
    unpipe 当用于读取数据的pipe方法被调用时触发
    error 当写入数据的过程中产生错误时触发

    这些对象在写入数据的过程中,所拥有的方法如下表所示:

    方法名 描述
    write 用于写入有数据
    end 当没有数据再被写入流中时调用该方法,这将迫使操作系统缓存区中的剩余

    使用fs模块的createWriteStream方法创建一个将流数据写入文件的WriteStream对象。

    const fs = require('fs');
    let file = fs.createWriteStream('./result.txt');
    file.write('hello Node.js',function(){
      console.log('写入文件')
    })
    
  • 相关阅读:
    为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?
    Weblogic12c安装与配置详解
    淘宝自己的前端框架KISSY(类似jquery)
    ExtJS4中initComponent和constructor的区别
    Servlet的getContextPath(), getServletPath(), getRequestURI(), getRealPath("/")
    Hash Join 一定是选择小表作为驱动表吗
    oracle for loop 简单
    oracle正则表达式
    Android开发--用户定位服务--UserLocation
    android蓝牙开发---与蓝牙模块进行通信
  • 原文地址:https://www.cnblogs.com/yinhaiying/p/10784880.html
Copyright © 2020-2023  润新知