Sign in
Sign up
Explore
Enterprise
Education
Search
Help
Terms of use
About Us
Explore
Enterprise
Education
Gitee Premium
Gitee AI
AI teammates
Sign in
Sign up
Fetch the repository succeeded.
Donate
Please sign in before you donate.
Cancel
Sign in
Scan WeChat QR to Pay
Cancel
Complete
Prompt
Switch to Alipay.
OK
Cancel
Watch
Unwatch
Watching
Releases Only
Ignoring
3
Star
45
Fork
21
DreamCoders
/
CoderGuide
Code
Issues
1169
Pull Requests
0
Wiki
Insights
Pipelines
Service
JavaDoc
PHPDoc
Quality Analysis
Jenkins for Gitee
Tencent CloudBase
Tencent Cloud Serverless
悬镜安全
Aliyun SAE
Codeblitz
SBOM
Don’t show this again
Update failed. Please try again later!
Remove this flag
Content Risk Flag
This task is identified by
as the content contains sensitive information such as code security bugs, privacy leaks, etc., so it is only accessible to contributors of this repository.
说说对 Node 中的 Stream 的理解?应用场景?
Backlog
#IAG9L0
陌生人
owner
Opened this issue
2024-07-29 16:04
<h2>一、是什么</h2><p>流(Stream),是一个数据传输手段,是端到端信息交换的一种方式,而且是有顺序的,是逐块读取数据、处理内容,用于顺序读取输入或写入输出</p><p><code>Node.js</code>中很多对象都实现了流,总之它是会冒数据(以 <code>Buffer</code> 为单位)</p><p>它的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中</p><p>流可以分成三部分:<code>source</code>、<code>dest</code>、<code>pipe</code></p><p>在<code>source</code>和<code>dest</code>之间有一个连接的管道<code>pipe</code>,它的基本语法是<code>source.pipe(dest)</code>,<code>source</code>和<code>dest</code>就是通过pipe连接,让数据从<code>source</code>流向了<code>dest</code>,如下图所示:</p><p><img src="https://static.ecool.fun//article/e676a4d2-5cbf-4541-8cd6-7770ac09c348.png" alt="" data-href="" style=""/></p><h2>二、种类</h2><p>在<code>NodeJS</code>,几乎所有的地方都使用到了流的概念,分成四个种类:</p><ul><li>可写流:可写入数据的流。例如 fs.createWriteStream() 可以使用流将数据写入文件</li><li>可读流: 可读取数据的流。例如fs.createReadStream() 可以从文件读取内容</li><li>双工流: 既可读又可写的流。例如 net.Socket</li><li>转换流: 可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据</li></ul><p>在<code>NodeJS</code>中<code>HTTP</code>服务器模块中,<code>request</code> 是可读流,<code>response</code> 是可写流。还有<code>fs</code> 模块,能同时处理可读和可写文件流</p><p>可读流和可写流都是单向的,比较容易理解,而另外两个是双向的</p><h3>双工流</h3><p>之前了解过<code>websocket</code>通信,是一个全双工通信,发送方和接受方都是各自独立的方法,发送和接收都没有任何关系</p><p>如下图所示:</p><p><img src="https://static.ecool.fun//article/9bc63359-6e40-4582-8bb5-4ab539b12f87.png" alt="" data-href="" style=""/></p><p>基本代码如下:</p><pre><code class="language-js">const { Duplex } = require('stream'); const myDuplex = new Duplex({ read(size) { // ... }, write(chunk, encoding, callback) { // ... } });</code></pre><h3>双工流</h3><p>双工流的演示图如下所示:</p><p><img src="https://static.ecool.fun//article/7e262767-786d-4abf-84a3-1a3f759a8a57.png" alt="" data-href="" style=""/></p><p>除了上述压缩包的例子,还比如一个 <code>babel</code>,把<code>es6</code>转换为,我们在左边写入 <code>es6</code>,从右边读取 <code>es5</code></p><p>基本代码如下所示:</p><pre><code class="language-js">const { Transform } = require('stream'); const myTransform = new Transform({ transform(chunk, encoding, callback) { // ... } });</code></pre><h2>三、应用场景</h2><p><code>stream</code>的应用场景主要就是处理<code>IO</code>操作,而<code>http</code>请求和文件操作都属于<code>IO</code>操作</p><p>思想一下,如果一次<code>IO</code>操作过大,硬件的开销就过大,而将此次大的<code>IO</code>操作进行分段操作,让数据像水管一样流动,知道流动完成</p><p>常见的场景有:</p><ul><li>get请求返回文件给客户端</li><li>文件操作</li><li>一些打包工具的底层操作</li></ul><h3>get请求返回文件给客户端</h3><p>使用<code>stream</code>流返回文件,<code>res</code>也是一个<code>stream</code>对象,通过<code>pipe</code>管道将文件数据返回</p><pre><code class="language-js">const server = http.createServer(function (req, res) { const method = req.method; // 获取请求方法 if (method === 'GET') { // get 请求 const fileName = path.resolve(__dirname, 'data.txt'); let stream = fs.createReadStream(fileName); stream.pipe(res); // 将 res 作为 stream 的 dest } }); server.listen(8000);</code></pre><h3>文件操作</h3><p>创建一个可读数据流<code>readStream</code>,一个可写数据流<code>writeStream</code>,通过<code>pipe</code>管道把数据流转过去</p><pre><code class="language-js">const fs = require('fs') const path = require('path') // 两个文件名 const fileName1 = path.resolve(__dirname, 'data.txt') const fileName2 = path.resolve(__dirname, 'data-bak.txt') // 读取文件的 stream 对象 const readStream = fs.createReadStream(fileName1) // 写入文件的 stream 对象 const writeStream = fs.createWriteStream(fileName2) // 通过 pipe执行拷贝,数据流转 readStream.pipe(writeStream) // 数据读取完成监听,即拷贝完成 readStream.on('end', function () { console.log('拷贝完成') }) </code></pre><h3>一些打包工具的底层操作</h3><p>目前一些比较火的前端打包构建工具,都是通过<code>node.js</code>编写的,打包和构建的过程肯定是文件频繁操作的过程,离不来<code>stream</code>,如<code>gulp</code></p>
<h2>一、是什么</h2><p>流(Stream),是一个数据传输手段,是端到端信息交换的一种方式,而且是有顺序的,是逐块读取数据、处理内容,用于顺序读取输入或写入输出</p><p><code>Node.js</code>中很多对象都实现了流,总之它是会冒数据(以 <code>Buffer</code> 为单位)</p><p>它的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中</p><p>流可以分成三部分:<code>source</code>、<code>dest</code>、<code>pipe</code></p><p>在<code>source</code>和<code>dest</code>之间有一个连接的管道<code>pipe</code>,它的基本语法是<code>source.pipe(dest)</code>,<code>source</code>和<code>dest</code>就是通过pipe连接,让数据从<code>source</code>流向了<code>dest</code>,如下图所示:</p><p><img src="https://static.ecool.fun//article/e676a4d2-5cbf-4541-8cd6-7770ac09c348.png" alt="" data-href="" style=""/></p><h2>二、种类</h2><p>在<code>NodeJS</code>,几乎所有的地方都使用到了流的概念,分成四个种类:</p><ul><li>可写流:可写入数据的流。例如 fs.createWriteStream() 可以使用流将数据写入文件</li><li>可读流: 可读取数据的流。例如fs.createReadStream() 可以从文件读取内容</li><li>双工流: 既可读又可写的流。例如 net.Socket</li><li>转换流: 可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据</li></ul><p>在<code>NodeJS</code>中<code>HTTP</code>服务器模块中,<code>request</code> 是可读流,<code>response</code> 是可写流。还有<code>fs</code> 模块,能同时处理可读和可写文件流</p><p>可读流和可写流都是单向的,比较容易理解,而另外两个是双向的</p><h3>双工流</h3><p>之前了解过<code>websocket</code>通信,是一个全双工通信,发送方和接受方都是各自独立的方法,发送和接收都没有任何关系</p><p>如下图所示:</p><p><img src="https://static.ecool.fun//article/9bc63359-6e40-4582-8bb5-4ab539b12f87.png" alt="" data-href="" style=""/></p><p>基本代码如下:</p><pre><code class="language-js">const { Duplex } = require('stream'); const myDuplex = new Duplex({ read(size) { // ... }, write(chunk, encoding, callback) { // ... } });</code></pre><h3>双工流</h3><p>双工流的演示图如下所示:</p><p><img src="https://static.ecool.fun//article/7e262767-786d-4abf-84a3-1a3f759a8a57.png" alt="" data-href="" style=""/></p><p>除了上述压缩包的例子,还比如一个 <code>babel</code>,把<code>es6</code>转换为,我们在左边写入 <code>es6</code>,从右边读取 <code>es5</code></p><p>基本代码如下所示:</p><pre><code class="language-js">const { Transform } = require('stream'); const myTransform = new Transform({ transform(chunk, encoding, callback) { // ... } });</code></pre><h2>三、应用场景</h2><p><code>stream</code>的应用场景主要就是处理<code>IO</code>操作,而<code>http</code>请求和文件操作都属于<code>IO</code>操作</p><p>思想一下,如果一次<code>IO</code>操作过大,硬件的开销就过大,而将此次大的<code>IO</code>操作进行分段操作,让数据像水管一样流动,知道流动完成</p><p>常见的场景有:</p><ul><li>get请求返回文件给客户端</li><li>文件操作</li><li>一些打包工具的底层操作</li></ul><h3>get请求返回文件给客户端</h3><p>使用<code>stream</code>流返回文件,<code>res</code>也是一个<code>stream</code>对象,通过<code>pipe</code>管道将文件数据返回</p><pre><code class="language-js">const server = http.createServer(function (req, res) { const method = req.method; // 获取请求方法 if (method === 'GET') { // get 请求 const fileName = path.resolve(__dirname, 'data.txt'); let stream = fs.createReadStream(fileName); stream.pipe(res); // 将 res 作为 stream 的 dest } }); server.listen(8000);</code></pre><h3>文件操作</h3><p>创建一个可读数据流<code>readStream</code>,一个可写数据流<code>writeStream</code>,通过<code>pipe</code>管道把数据流转过去</p><pre><code class="language-js">const fs = require('fs') const path = require('path') // 两个文件名 const fileName1 = path.resolve(__dirname, 'data.txt') const fileName2 = path.resolve(__dirname, 'data-bak.txt') // 读取文件的 stream 对象 const readStream = fs.createReadStream(fileName1) // 写入文件的 stream 对象 const writeStream = fs.createWriteStream(fileName2) // 通过 pipe执行拷贝,数据流转 readStream.pipe(writeStream) // 数据读取完成监听,即拷贝完成 readStream.on('end', function () { console.log('拷贝完成') }) </code></pre><h3>一些打包工具的底层操作</h3><p>目前一些比较火的前端打包构建工具,都是通过<code>node.js</code>编写的,打包和构建的过程肯定是文件频繁操作的过程,离不来<code>stream</code>,如<code>gulp</code></p>
Comments (
0
)
Sign in
to comment
Status
Backlog
Backlog
Doing
Done
Closed
Assignees
Not set
Labels
Node
Not set
Label settings
Milestones
No related milestones
No related milestones
Pull Requests
None yet
None yet
Successfully merging a pull request will close this issue.
Branches
No related branch
No related branch
master
Planed to start   -   Planed to end
-
Top level
Not Top
Top Level: High
Top Level: Medium
Top Level: Low
Priority
Not specified
Serious
Main
Secondary
Unimportant
参与者(1)
1
https://gitee.com/DreamCoders/CoderGuide.git
git@gitee.com:DreamCoders/CoderGuide.git
DreamCoders
CoderGuide
CoderGuide
Going to Help Center
Search
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
Comment
Repository Report
Back to the top
Login prompt
This operation requires login to the code cloud account. Please log in before operating.
Go to login
No account. Register