首页 > 其他分享 >Stream 的基础

Stream 的基础

时间:2024-03-05 14:55:17浏览次数:25  
标签:读取 Stream 分块 一个 基础 reader 数据 cpu

零、参考资料

一、对概念的理解

"流"(stream)是一个很抽象的概念,《C程序设计语言》中这样定义:流与磁盘或其它外围设备关联的数据的源或目的地。 - 一样的费解。 从字面意义上,我们能找到的最贴合的是"水流",因此,通俗意义上就可以解释成像水流一样长长的一串的东西。 物质意义上的水流,是作为内容的水+作为外部的容器+时间共同形成,而在编程语言中的流,并不严格采用这三样基本元素。 编程语言中,流是对数据的一种描述,是一个视图,是一个对象,因此,很可能是先有一个视图(壳,空的容器),其次才与数据(水)关联,最后在时间的作用下数据逐步进入视图中,形成编程意义上的"流" 不过流不是容器,其内涵远不止容器,或者说,容器可以被视作一个流,以流的形式进行读写操作。

二、为什么会有流

流的概念挺抽象的,这个概念的产生自然有其应用场景。所以在 JavaScript 中,流是为何而产生? 其实很简单,数据从一个媒介进入到另外一个媒介是有成本的。我们都知道在计算机架构中,cpu 运算速度最快,但是不存储数据,硬盘存储数据,但是运算速度慢,所以这就有了时间差,即使在目前的架构中有内存、缓存等的设计,但是这个矛盾始终存在。而网络与计算机 cpu 的速度差就更明显了,总不能一直把 cpu 锁着,等网络数据全部加载完成再去进行运算。所以流就是在这样的需求下产生了。说白了,就是数据来一点,让 cpu 处理一点,数据没来,释放 cpu,让 cpu 去处理其他程序

三、js 中与流相关的术语和概念

(一)可读流

一个可读流是一个数据源,在 JavaScript 中用一个 ReadableStream 对象表示,数据从它的底层源(underlying source)流出——底层源表示一个你希望从中获取数据,且来自网络或其他域的某种资源(比如某些硬件的输出流)
  • chunk - 分块:FE 打包工具中也有这个概念,将各个组件分成独立单元,打包成独立文件,这样在运行时环境中可以按需加载。对于数据,也是类似的概念。数据(字节、类型化数组)被按序读入(分割成)很多小的片段,这些小的片段就是 chunk
  • enqueued - 入队:讲这些分块有序放入流中,这个操作就是入队 —— 这意味着它们已经在队列中排队等待被读取。流的一个内置队列跟踪了那些尚未读取的分块
  • reader - 读取流中分块的对象
  • controller - 与 reader 关联的控制对象,用来控制流(如:关闭流等操作)
  • consumer - 消费(程序):既然是可读的,那么就需要被读取,读取的过程即为 consumer,是 reader 和它一起运行的其他处理代码的综合过程
特点:
  • 同一时间,consumer 只能处理一个分块,但是能对这个分块进行任何类型的操作
  • 一个(可读)流只能被一个 reader 读取,如果想被其他 reader 读取,必须想取消掉前一个 reader
根据这些特点,拷贝(teeing)就应运而生:将一个流分割成两个相同的副本,这两个副本从内容上与分割器前的流是完全相同的,因此就能被两个独立的 reader 读取,这个分割过程就是拷贝

(二)可写流

与可读流相对,其概念上是与可读流相反,是对外输出的

(三)其他

  • 链式管道(pipe chain)传输:这个概念呢着重在转换上,说白了就是将一个流转成另外一个流,当然在过程中开发者可以完成数据的操作。因此在这个过程中流至少是成对出现的。链式管道传输的起点称为原始源(original source),终点称为最终接收器(ultimate sink)
  • 背压(backpressure):单个流或一个链式管道调节读/写速度的过程。当链中后面的一个流仍然忙碌,尚未准备好接受更多的分块时,它会通过链向上游的流发送一个信号,告诉上游的转换流(或原始源)适当地减慢传输速度,这样你就不会在任何地方遇到瓶颈 - 这个似乎与硬件相关,实际编程中用处似乎不大

四、流和缓冲区

这两个从功能上没什么太大的差别,都是为了解决不同运算速度的设备之间的数据传输问题,但是流更接近抽象的层面,属于程序/语言方面。而缓冲区则更偏向硬件的层面,在 MDN 中("缓冲区是物理内存中的一个存储区域,当数据进行转移时用来临时存放数据")中直接就将其简化成物理内存的一块区域
因此,如果这样来看的话,在程序软件到硬件的整条链路中,流的处理速度会比缓冲区的更快一点,即:程序 - 流 - 缓冲区 - 硬件

标签:读取,Stream,分块,一个,基础,reader,数据,cpu
From: https://www.cnblogs.com/cc-freiheit/p/18054030

相关文章

  • sql注入--基础注入判断方法(构造闭合)
    在我们拿到一个sql注入的题目之后,在确定了注入点之后,接下来要做的事情就是进行基础注入判断。在开始前,我们需要理解一个SQL注入中最常用的词汇——构造闭合。对于SQL处理语句后台的写法:SELECTusername,passwordFROMusersWHEREid=?这里的问号可以有多种的闭合方式,......
  • 前端基础学习1 | Web、Html、CSS
    前端基础学习1|Web、Html、CSS1、Web基础知识Web(wwwWorldWideWeb),全球广域网,也称万维网,能够通过浏览器访问的网站Web网站的工作流程Web标准,也称为网页标准,由一些列的标准组成,大部分由W3C(WorldWideWebConsortium,万维网联盟)负责制定。Web标准由三个部分组成:HTML:......
  • 1.Python3 基础语法
    Python3基础语法Python3中文官方文档https://docs.python.org/zh-cn/3.9/Python标准库https://docs.python.org/zh-cn/3.9/library/index.html1.Python保留字保留字即关键字,我们不能把它们用作任何标识符名称。Python的标准库提供了一个keyword模块,可以输出当前版本的......
  • JAVA基础--JavaDos生成文档
    JavaDos生成文档法一:通过命令行生成信息输入(例子)/***@authorAAA*@version1.0*@since1.8*/publicclassDos{Stringname;/***@authorAAA*@paramname*@return*@throwsException*///方法前输入/**则会自......
  • JAVA基础--包机制
    JAVA包机制(使用IntellijIDEA)语法格式注意:该语句位于第一行,不可删除或改变位置packagepkg1[.pag2[.pag3...]];packagecom.baidu.www;命名规则一般利用公司域名倒置作为包名例如:www.baidu.com,包名写为:com.baidu.www导入包为了能够使用某一包内的成员,需要在Java程序中明......
  • Docker容器实战(00)-基础命令大全
    1容器生命周期管理1.1dockerstart启动一或多个已被停止的容器。#启动已被停止的容器myrunoobdockerstartmyrunoob1.2dockerstop停止一个运行中的容器dockerstopmyrunoob1.3dockerrestart重启容器dockerrestartmyrunoob1.4dockerrun创建一个新的容......
  • [基础] Transformer
    Transformer)名称解释:Self-Attention:类似于CNN里面的Conv层,是Transformer中重复次数最多的特征提取Layer。Multi-HeadAttention:相对于Self-Attention,将每个节点外接多个q、k、vhead。CrossAttention:Decoder提取Encoder输出特征的桥梁,原理是用Decoder的q去queryEn......
  • Java基础复习题1-100
    JAVA基础1~100下列哪个关键字可以使成员变量或方法不被子类继承? CA.static B.final C.private D.protectedprivate关键字被用来修饰成员变量或方法,表示它们只能在当前类内部访问,无法被其他类或子类访问。当一个成员被声明为private后,它就成为了该类的私有成员,只能在该类......
  • Java基础复习题201-290
    JAVA基础201~290Java中的接口可以包含实现代码。 BA.正确 B.错误在Java中,数组元素的下标从0开始。 AA.正确 B.错误在Java中,System.out.println()方法可以用于在控制台输出文本。 AA.正确 B.错误在Java中,静态变量和实例变量的值都存在对象内存空间中。 BA.......
  • Java基础复习题101-200
    JAVA基础101~200在Java中,while和do-while循环的区别是,do-while循环至少会执行一次循环体。 AA.正确 B.错误在Java中,do-while循环和while循环的区别在于条件判断的位置。while循环先判断条件是否为真,然后再执行循环体;而do-while循环先执行一次循环体,然后再判断条件是否为真......