不论是否是科班出身,认真读完,想必会给你带去一些收获,文字较多
如果你在Node.js中遇到像Buffer,Stream、二进制数据这样的词,你会像我一样迷惑吗? 这种感觉是否让你认为【知其然,不必知其所以然,会用即可】,而这些东西只是让Node.js的大师和包开发者理解?
令人遗憾的是,许多教程和书籍将直接教导如何使用Node.js包来开发Web应用程序,而不让您了解Node.js的核心功能以及它们存在的原因。有些人会公然告诉你,你不需要了解他们,因为你可能不会直接操作他们。
好吧,如果你选择保持一个普通的Node.js开发者,你可能不会直接操作他们。
然而,如果神秘[mysteries]事物让你产生好奇[curious],你会尽可能地满足你的好奇心,如果你想让你的Node.js理解更上一层楼,那么你真的需要深入了解许多核心特性例如Node.js,比如Buffer。这正是我写这篇文章的原因 - 帮助我们揭开其中一些功能的神秘面纱,并将我们的Node.js学习提升到一个新的水平。
在介绍Buffer时,官方的Node.js文档部分陈述了......
… mechanism for reading or manipulating streams of binary data. The Buffer class was introduced as part of the Node.js API to make it possible to interact with octet streams in the context of things like TCP streams and file system operations.
嗯,除非你事先[prior]知道上述句子中的所有单词[sentences],否则它们可能只是一堆行话[jargon]。我们试着简化这一点,改述[改述]它,这样我们就可以有一个清晰的理解,不会被那里的许多花里胡哨分散注意力。从该介绍中提取,我们可以准确地说:
该Buffer类介绍了作为Node.js的API的一部分,以使其能够操纵或二进制数据流进行交互。
现在更简单了吗?但是.....Buffer, Streams,二进制数据......还有很多大词。那么,让我们尝试解决从最后到第一个这些大字。
二进制数据 是什么?
你可能已经知道计算机存储和表示二进制数据。二进制只是一组或一个1和0的集合。例如,以下是五个不同的二进制文件,五个不同的1和0的集合:
10,01,001,1110,00101011
二进制中的每个数字,每个数字1和0一个集合都称为一个Bit,它是二进制Binary digIT 的简写形式。
为了存储或表示一段数据,计算机需要将该数据转换为其二进制表示。例如,要存储数字12,计算机需要将12转换为其二进制表示1100。
计算机如何知道如何执行此转换?那么,这是纯粹的数学。这是我们在基础数学中学到的简单二进制数字系统 - 在基数2数字系统中表示一个数字。电脑了解数学。
但是数字并不是我们使用的唯一数据类型。我们也有字符串,图片,甚至视频。计算机知道如何表示二进制文件中的所有类型的数据。 例如,我们以字符串为例。计算机如何在二进制文件中表示字符串“L”?要将任何字符存储在二进制文件中,计算机将首先将该字符转换为数字,然后将该数字转换为其二进制表示形式。因此,对于字符串“L”, 计算机将首先将L转换为代表L的数字。让我们看看如何。
打开浏览器控制台并粘贴以下代码片段,然后按Enter键:"L".charCodeAt(0)。你看见什么了?数字76?这是字符L的数字表示或字符代码或代码点。但是计算机如何知道每个角色代表什么确切的数字?它如何知道用数字76来表示L?
字符集
字符集 定义了确切数字代表每个字符的规则。我们对这些规则有不同的定义。非常受欢迎的包括Unicode和ASCII。JavaScript在Unicode字符集中的效果非常好。事实上,它是在浏览器中,指出76应表示Unicode 大号。
所以我们已经看到计算机如何在数字中表示字符。现在,计算机将依次代表数字76到二进制表示。您可能会认为,只需将76转换为基数为2的数字系统即可。没那么快!
字符编码
正如有些规则定义了什么样的数字应该代表一个字符一样,还有一些规则定义了如何在二进制文件中表示该数字。具体来说,用多少位来表示数字。这被称为【字符编码】
字符编码的一个定义是UTF-8。UTF-8规定字符应该以字节编码。 一个字节是一组8位-八个1和0
。所以八个1和0应该用来表示任何二进制字符的代码点。
为了理解这一点,正如我们前面提到的, 数字12的二进制表示是1100。所以当UTF-8声明12位应该是8位时
,UTF-8就是说计算机需要在实际的基数为2的数字12的左边添加更多的位,使其成为一个字节。所以12应该被存储为00001100。说得通?
因此,76应该被存储为01001100。
这是计算机如何在二进制文件中存储字符串或字符。同样,计算机也有图像和视频如何转换或编码和存储在二进制文件中的规定。这里的重点是,计算机将所有数据类型存储在二进制文件中,这就是所谓的二进制数据。
如果你对字符编码的本质特别感兴趣,你可以查看这个详细的介绍。,否则你Google下,再不行百度了解下。
现在我们了解什么是二进制数据,但是从我们的介绍到缓冲区的二进制数据流是什么 ?
流
Node.js中的流只是意味着一段时间内从一个点移动到另一个点的数据序列。整个概念是,需要处理大量的数据,但在开始处理之前不需要等待所有数据可用。
基本上,这些大数据被分解并以大块形式发送。因此,从缓冲区的原始定义(“在......文件系统的上下文中的二进制数据流...”),这仅仅意味着二进制数据在文件系统中被移动。例如,将存储在file1.txt中的文本移动到file2.txt。
但是,缓冲区如何帮助我们在流式传输过程中与二进制数据交互或操作?什么是这个缓冲区btw?
缓冲
我们已经看到,数据流是从一个点到另一个点的数据移动,但它们究竟是如何移动的?
通常情况下,数据的移动通常意在处理它,或读取数据,并根据数据做出决定。但是,一个过程可能需要一段时间的最小和最大数据量。因此,如果数据到达的速度比进程消耗数据的速率更快,那么超出的数据需要等待某个地方进行处理。
另一方面,如果进程消耗的数据比它到达的速度快,那么到达的少数数据需要等待一定数量的数据到达后再发送出去处理。
那个“等候区”就是缓冲区!它是计算机中的一个小型物理位置,通常位于RAM中,数据在这里暂时收集,等待并最终在流式传输过程中发送出去进行处理。
我们可以将整个流和缓冲过程视为公共汽车站。在一些公交车站,一辆公共汽车不允许离开,直到有一定数量的乘客抵达或特定的出发时间。另外,乘客可能以不同的速度到达不同的时间。乘客和公车站都不能控制乘客到达车站。
无论如何,早些抵达的乘客需要等到公交车站决定派车前往。当公共汽车已经装载或当公共汽车已经离开时到达的乘客需要等待下一辆公共汽车。
无论如何,总会有一个等待的地方。这就是Node.js 的缓冲区!Node.js无法控制数据到达的速度或时间,流的速度。它只能决定何时发送数据。如果还没有时间,Node.js会将它们放入缓冲区 - “等待区” - RAM中的一个小地方,直到需要将它们发送出去处理。
一个典型的例子,你可以看到缓冲区的行动是当你在线传输视频。如果您的互联网连接足够快,流的速度将足够快,以立即填满缓冲区并将其发送出去进行处理,然后再填充另一个,然后将其发送出去,然后再发送出去,然后再发送另一个......直到流完成
但是如果你的连接速度 很慢
,在处理到达第一组数据后,视频播放器将显示一个加载图标,或显示“缓冲”文本,这意味着收集更多数据或等待更多数据到达。当缓冲区被填满并被处理时,播放器显示数据,视频。在播放时,更多数据将继续到达,并在缓冲区中等待。
如果玩家正在处理或播放先前的数据,并且缓冲区尚未填满,则将再次显示“缓冲”文本,等待收集更多数据进行处理。
那是缓冲区!
从缓冲区的原始定义中可以看出,在缓冲区中,我们可以操纵正在流式传输的二进制数据或与其进行交互。这种原始二进制数据可能会与我们进行什么样的交互?Node.js中的Buffer实现为我们提供了可用的完整列表。让我们看看其中的一些。
与缓冲区交互
甚至可以创建自己的缓冲区!除了一个Node.js会在流中自动创建的时候,可以创建和操作自己的缓冲区。让我们创建一个!
根据你想达到的目标,有不同的方法来创建一个缓冲区。让我们看看一些。
// Create an empty buffer of size 10.
// A buffer that only can accommodate 10 bytes.
const buf1 = Buffer.alloc(10);
// Create a buffer with content
const buf2 = Buffer.from("hello buffer");
一旦你的缓冲区已经被创建,你可以开始与它进行交互
// Examine the structure of a buffer
buf1.toJSON()
// { type: 'Buffer', data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }
// an empty buffer
buf2.toJSON()
// { type: 'Buffer',
data: [
104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114
]
}
// the toJSON() method presents the data as the Unicode Code Points of the characters
// Examine the size of a buffer
buf1.length // 10
buf2.length // 12. Auto-assigned based on the initial content when created.
// Write to a buffer
buf1.write("Buffer really rocks!")
// Decode a buffer
buf1.toString() // 'Buffer rea'
//oops, because buf1 is created to contain only 10 bytes, it couldn't accommodate the rest of the characters
// Compare two buffers
我们可以通过一个缓冲区进行很多互动。前往官方文档,以更多地使用这些方法。
最后,我将为您解答这个小挑战:阅读Node.js的核心库之一zlib.js的源代码,了解它如何利用缓冲区的能力来操纵二进制数据流。这些变成了gziped文件。当你阅读时,记下你学到的东西,并在评论中与我们分享。
我希望这篇介绍帮助你更好地理解Node.js Buffer。
如果您觉得自己做得不错,而其他人则有机会看到这一点,请亲切点赞文章,以帮助我们更好地了解Node.js社区中的缓冲区。
能认真读完到这里的,实乃不易之才!祝你好运!
欢迎关注微信公众号: IT实战联盟
注意:本文归作者所有,未经作者允许,不得转载