node缓冲区
The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.
作者选择了COVID-19救济基金来接受捐赠,这是Write for DOnations计划的一部分。
A buffer is a space in memory (typically RAM) that stores binary data. In Node.js, we can access these spaces of memory with the built-in Buffer
class. Buffers store a sequence of integers, similar to an array in JavaScript. Unlike arrays, you cannot change the size of a buffer once it is created.
缓冲区是内存(通常是RAM)中存储二进制数据的空间。 在Node.js中 ,我们可以使用内置的Buffer
类访问这些内存空间。 缓冲区存储整数序列,类似于JavaScript中的数组 。 与数组不同,创建缓冲区后就无法更改其大小。
You may have used buffers implicitly if you wrote Node.js code already. For example, when you read from a file with fs.readFile()
, the data returned to the callback or Promise is a buffer object. Additionally, when HTTP requests are made in Node.js, they return data streams that are temporarily stored in an internal buffer when the client cannot process the stream all at once.
如果您已经编写了Node.js代码,则可能隐式使用了缓冲区。 例如,当您使用fs.readFile()
从文件中读取数据时,返回到回调或Promise的数据是一个缓冲区对象 。 此外,在Node.js中发出HTTP请求时,当客户端无法一次处理所有请求时,它们将返回临时存储在内部缓冲区中的数据流。
Buffers are useful when you’re interacting with binary data, usually at lower networking levels. They also equip you with the ability to do fine-grained data manipulation in Node.js.
当您与二进制数据进行交互时(通常在较低的网络级别上),缓冲区很有用。 他们还使您具备在Node.js中进行细粒度数据处理的能力。
In this tutorial, you will use the Node.js REPL to run through various examples of buffers, such as creating buffers, reading from buffers, writing to and copying from buffers, and using buffers to convert between binary and encoded data. By the end of the tutorial, you’ll have learned how to use the Buffer
class to work with binary data.
在本教程中,您将使用Node.js REPL遍历各种缓冲区示例,例如创建缓冲区,从缓冲区读取,从缓冲区写入和复制以及使用缓冲区在二进制数据和编码数据之间进行转换。 在本教程结束时,您将学习如何使用Buffer
类来处理二进制数据。
You will need Node.js installed on your development machine. This tutorial uses version 10.19.0. To install this on macOS or Ubuntu 18.04, follow the steps in How To Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.
您将需要在开发计算机上安装Node.js。 本教程使用版本10.19.0。 要将其安装在macOS或Ubuntu 18.04上,请遵循如何在macOS上安装Node.js并创建本地开发环境中的步骤,或如何在Ubuntu 18.04上安装Node.js的 使用PPA安装部分中的步骤 。
In this tutorial, you will interact with buffers in the Node.js REPL (Read-Evaluate-Print-Loop). If you want a refresher on how to use the Node.js REPL effectively, you can read our guide on How To Use the Node.js REPL.
在本教程中,您将与Node.js REPL(Read-Evaluate-Print-Loop)中的缓冲区进行交互。 如果您想重新了解如何有效使用Node.js REPL,可以阅读有关如何使用Node.js REPL的指南 。
For this article we expect the user to be comfortable with basic JavaScript and its data types. You can learn those fundamentals with our How To Code in JavaScript series.
对于本文,我们希望用户对基本JavaScript及其数据类型感到满意。 您可以通过我们的“ 如何编写JavaScript代码”系列学习这些基础知识。
This first step will show you the two primary ways to create a buffer object in Node.js.
第一步将向您展示在Node.js中创建缓冲区对象的两种主要方法。
To decide what method to use, you need to answer this question: Do you want to create a new buffer or extract a buffer from existing data? If you are going to store data in memory that you have yet to receive, you’ll want to create a new buffer. In Node.js we use the alloc()
function of the Buffer
class to do this.
要决定使用哪种方法,您需要回答以下问题:您要创建一个新的缓冲区还是要从现有数据中提取缓冲区? 如果要将数据存储在尚未接收的内存中,则需要创建一个新的缓冲区。 在Node.js中,我们使用Buffer
类的alloc()
函数执行此操作。
Let’s open the Node.js REPL to see for ourselves. In your terminal, enter the node
command:
让我们打开Node.js REPL自己看看。 在您的终端中,输入node
命令:
You will see the prompt begin with >
.
您将看到提示以>
开头。
The alloc()
function takes the size of the buffer as its first and only required argument. The size is an integer representing how many bytes of memory the buffer object will use. For example, if we wanted to create a buffer that was 1KB (kilobyte) large, equivalent to 1024 bytes, we would enter this in the console:
alloc()
函数将缓冲区的大小作为第一个也是唯一的必需参数。 该大小是一个整数,表示缓冲区对象将使用多少内存字节。 例如,如果我们要创建一个大小为1KB(千字节)的缓冲区,相当于1024个字节,则可以在控制台中输入以下内容:
To create a new buffer, we used the globally available Buffer
class, which has the alloc()
method. By providing 1024
as the argument for alloc()
, we created a buffer that’s 1KB large.
为了创建一个新的缓冲区,我们使用了全局可用的Buffer
类,该类具有alloc()
方法。 通过提供1024
作为alloc()
的参数,我们创建了一个1KB大的缓冲区。
By default, when you initialize a buffer with alloc()
, the buffer is filled with binary zeroes as a placeholder for later data. However, we can change the default value if we’d like to. If we wanted to create a new buffer with 1
s instead of 0
s, we would set the alloc()
function’s second parameter—fill
.
默认情况下,当您使用alloc()
初始化缓冲区时,该缓冲区将填充二进制零作为以后数据的占位符。 但是,我们可以根据需要更改默认值。 如果我们想用1
s而不是0
s创建一个新的缓冲区,我们将设置alloc()
函数的第二个参数fill
。
In your terminal, create a new buffer at the REPL prompt that’s filled with 1
s:
在您的终端中,在REPL提示符下创建一个新缓冲区,该缓冲区充满1
s:
We just created a new buffer object that references a space in memory that stores 1KB of 1
s. Although we entered an integer, all data stored in a buffer is binary data.
我们刚刚创建了一个新的缓冲区对象在内存中引用的空间,用于存储1KB的1
秒。 尽管我们输入了整数,但是存储在缓冲区中的所有数据都是二进制数据。
Binary data can come in many different formats. For example, let’s consider a binary sequence representing a byte of data: 01110110
. If this binary sequence represented a string in English using the ASCII encoding standard, it would be the letter v
. However, if our computer was processing an image, that binary sequence could contain information about the color of a pixel.
二进制数据可以采用许多不同的格式。 例如,让我们考虑一个表示数据字节的二进制序列: 01110110
。 如果此二进制序列使用ASCII编码标准表示英文字符串 , 则为字母v
。 但是,如果我们的计算机正在处理图像,则该二进制序列可能包含有关像素颜色的信息。
The computer knows to process them differently because the bytes are encoded differently. Byte encoding is the format of the byte. A buffer in Node.js uses the UTF-8 encoding scheme by default if it’s initialized with string data. A byte in UTF-8 represents a number, a letter (in English and in other languages), or a symbol. UTF-8 is a superset of ASCII, the American Standard Code for Information Interchange. ASCII can encode bytes with uppercase and lowercase English letters, the numbers 0-9, and a few other symbols like the exclamation mark (!) or the ampersand sign (&).
由于字节的编码方式不同,因此计算机知道以不同的方式处理它们。 字节编码是字节的格式。 如果使用字符串数据初始化了Node.js中的缓冲区,则默认情况下使用UTF-8编码方案。 UTF-8中的字节代表数字,字母(英语和其他语言)或符号。 UTF-8是ASCII (美国信息交换标准代码)的超集。 ASCII可以使用大写和小写英文字母,数字0-9以及其他一些符号(例如感叹号( ! )或&符号( & ))对字节进行编码。
If we were writing a program that could only work with ASCII characters, we could change the encoding used by our buffer with the alloc()
function’s third argument—encoding
.
如果编写的程序只能使用ASCII字符,则可以使用alloc()
函数的第三个参数encoding
来更改缓冲区使用的encoding
。
Let’s create a new buffer that’s five bytes long and stores only ASCII characters:
让我们创建一个新的缓冲区,该缓冲区长5个字节,并且仅存储ASCII字符:
The buffer is initialized with five bytes of the character a
, using the ASCII representation.
使用ASCII表示,使用字符a
五个字节初始化缓冲区。
Note: By default, Node.js supports the following character encodings:
注意 :默认情况下,Node.js支持以下字符编码:
ASCII, represented as ascii
ASCII ,表示为ascii
UTF-8, represented as utf-8
or utf8
UTF-8 ,表示为utf-8
或utf8
UTF-16, represented as utf-16le
or utf16le
UTF-16 ,表示为utf-16le
或utf16le
UCS-2, represented as ucs-2
or ucs2
UCS-2 ,表示为ucs-2
或ucs2
Base64, represented as base64
Base64 ,表示为base64
Hexadecimal, represented as hex
十六进制 ,表示为hex
ISO/IEC 8859-1, represented as latin1
or binary
ISO / IEC 8859-1 ,表示为latin1
或binary
All of these values can be used in Buffer class functions that accept an encoding
parameter. Therefore, these values are all valid for the alloc()
method.
所有这些值都可以在接受encoding
参数的Buffer类函数中使用。 因此,这些值对于alloc()
方法都是有效的。
So far we’ve been creating new buffers with the alloc()
function. But sometimes we may want to create a buffer from data that already exists, like a string or array.
到目前为止,我们一直在使用alloc()
函数创建新的缓冲区。 但是有时我们可能想从已经存在的数据(例如字符串或数组)创建缓冲区。
To create a buffer from pre-existing data, we use the from()
method. We can use that function to create buffers from:
要从现有数据创建缓冲区,我们使用from()
方法。 我们可以使用该函数从以下位置创建缓冲区:
An array of integers: The integer values can be between 0
and 255
.
整数数组:整数值可以在0
到255
之间。
An ArrayBuffer
: This is a JavaScript object that stores a fixed length of bytes.
ArrayBuffer
:这是一个JavaScript对象,用于存储固定长度的字节。
Other JavaScript objects that have a Symbol.toPrimitive
property. That property tells JavaScript how to convert the object to a primitive data type: boolean
, null
, undefined
, number
, string
, or symbol
. You can read more about Symbols at Mozilla’s JavaScript documentation.
具有Symbol.toPrimitive
属性的其他JavaScript对象。 该属性告诉JavaScript如何将对象转换为原始数据类型: boolean
, null
, undefined
, number
, string
或symbol
。 您可以在MozillaJavaScript 文档中阅读有关符号的更多信息。
Let’s see how we can create a buffer from a string. In the Node.js prompt, enter this:
让我们看看如何从字符串创建缓冲区。 在Node.js提示中,输入以下内容:
We now have a buffer object created from the string My name is Paul
. Let’s create a new buffer from another buffer we made earlier:
现在,我们有了一个由字符串创建的缓冲区对象, My name is Paul
。 让我们从之前创建的另一个缓冲区中创建一个新缓冲区:
We’ve now created a new buffer asciiCopy
that contains the same data as asciiBuf
.
现在,我们创建了一个新缓冲区asciiCopy
,其中包含与asciiBuf
相同的数据。
Now that we have experienced creating buffers, we can dive into examples of reading their data.
既然我们具有创建缓冲区的经验,那么我们就可以深入研究读取其数据的示例。
There are many ways to access data in a Buffer. We can access an individual byte in a buffer or we can extract the entire contents.
有许多方法可以访问缓冲区中的数据。 我们可以访问缓冲区中的单个字节,也可以提取全部内容。
To access one byte of a buffer, we pass the index or location of the byte we want. Buffers store data sequentially like arrays. They also index their data like arrays, starting at 0
. We can use array notation on the buffer object to get an individual byte.
要访问缓冲区的一个字节,我们传递所需字节的索引或位置。 缓冲区像数组一样顺序存储数据。 他们还像数组一样索引其数据,从0
开始。 我们可以在缓冲区对象上使用数组符号来获取单个字节。
Let’s see how this looks by creating a buffer from a string in the REPL:
让我们通过在REPL中的字符串创建一个缓冲区来看看它的外观:
Now let’s read the first byte of the buffer:
现在让我们读取缓冲区的第一个字节:
As you press ENTER
, the REPL will display:
当您按ENTER
,REPL将显示:
Output
72
The integer 72
corresponds the UTF-8 representation for the letter H
.
整数72
对应于字母H
的UTF-8表示形式。
Note: The values for bytes can be numbers between 0
and 255
. A byte is a sequence of 8 bits. A bit is binary, and therefore can only have one of two values: 0
or 1
. If we have a sequence of 8 bits and two possible values per bit, then we have a maximum of 2⁸ possible values for a byte. That works out to a maximum of 256 values. Since we start counting from zero, that means our highest number is 255.
注意 :字节的值可以是0
到255
之间的数字。 一个字节是8位的序列。 位是二进制的,因此只能具有两个值之一: 0
或1
。 如果我们有一个8位的序列,每位有两个可能的值,那么一个字节最多有2个可能的值。 最多可计算256个值。 由于我们从零开始计数,因此我们的最高数为255。
Let’s do the same for the second byte. Enter the following in the REPL:
让我们对第二个字节做同样的事情。 在REPL中输入以下内容:
The REPL returns 105
, which represents the lowercase i
.
REPL返回105
,代表小写字母i
。
Finally, let’s get the third character:
最后,让我们获得第三个字符:
You will see 33
displayed in the REPL, which corresponds to !
.
您将看到REPL中显示33
,它对应于!
。
Let’s try to retrieve a byte from an invalid index:
让我们尝试从无效索引中检索一个字节:
The REPL will return:
REPL将返回:
Output
undefined
This is just like if we tried to access an element in an array with an incorrect index.
这就像我们尝试使用错误的索引访问数组中的元素一样。
Now that we’ve seen how to read individual bytes of a buffer, let’s see our options for retrieving all the data stored in a buffer at once. The buffer object comes with the toString()
and the toJSON()
methods, which return the entire contents of a buffer in two different formats.
既然我们已经了解了如何读取缓冲区的各个字节,那么让我们看看用于一次检索缓冲区中存储的所有数据的选项。 缓冲区对象带有toString()
和toJSON()
方法,它们以两种不同的格式返回缓冲区的全部内容。
As its name suggests, the toString()
method converts the bytes of the buffer into a string and returns it to the user. If we use this method on hiBuf
, we will get the string Hi!
. Let’s try it!
顾名思义, toString()
方法将缓冲区的字节转换为字符串并将其返回给用户。 如果在hiBuf
上使用此方法,则将获得字符串Hi!
。 试试吧!
In the prompt, enter:
在提示中,输入:
The REPL will return:
REPL将返回:
Output
'Hi!'
That buffer was created from a string. Let’s see what happens if we use the toString()
on a buffer that was not made from string data.
该缓冲区是从字符串创建的。 让我们看看如果在不是由字符串数据组成的缓冲区上使用toString()
会发生什么。
Let’s create a new, empty buffer that’s 10
bytes large:
让我们创建一个新的空缓冲区,其大小为10
个字节:
Now, let’s use the toString()
method:
现在,让我们使用toString()
方法:
We will see the following result:
我们将看到以下结果:
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'
The string \u0000
is the Unicode character for NULL
. It corresponds to the number 0
. When the buffer’s data is not encoded as a string, the toString()
method returns the UTF-8 encoding of the bytes.
字符串\u0000
是NULL
的Unicode字符。 它对应于数字0
。 当缓冲区的数据未编码为字符串时, toString()
方法将返回字节的UTF-8编码。
The toString()
has an optional parameter, encoding
. We can use this parameter to change the encoding of the buffer data that’s returned.
toString()
有一个可选参数encoding
。 我们可以使用此参数来更改返回的缓冲区数据的编码。
For example, if you wanted the hexadecimal encoding for hiBuf
you would enter the following at the prompt:
例如,如果您想要hiBuf
的十六进制编码, hiBuf
在提示符下输入以下内容:
That statement will evaluate to:
该声明将评估为:
Output
'486921'
486921
is the hexadecimal representation for the bytes that represent the string Hi!
. In Node.js, when users want to convert the encoding of data from one form to another, they usually put the string in a buffer and call toString()
with their desired encoding.
486921
是代表字符串Hi!
的字节的十六进制表示形式Hi!
。 在Node.js中,当用户想要将数据的编码从一种形式转换为另一种形式时,他们通常将字符串放入缓冲区中,并使用所需的编码来调用toString()
。
The toJSON()
method behaves differently. Regardless of whether the buffer was made from a string or not, it always returns the data as the integer representation of the byte.
toJSON()
方法的行为有所不同。 无论缓冲区是否由字符串组成,它始终以字节的整数表示形式返回数据。
Let’s re-use the hiBuf
and tenZeroes
buffers to practice using toJSON()
. At the prompt, enter:
让我们重新使用hiBuf
和tenZeroes
缓冲区来练习使用toJSON()
。 在提示符下,输入:
The REPL will return:
REPL将返回:
Output
{ type: 'Buffer', data: [ 72, 105, 33 ] }
The JSON object has a type
property that will always be Buffer
. That’s so programs can distinguish these JSON object from other JSON objects.
JSON对象具有type
属性,该属性将始终为Buffer
。 因此,程序可以将这些JSON对象与其他JSON对象区分开。
The data
property contains an array of the integer representation of the bytes. You may have noticed that 72
, 105
, and 33
correspond to the values we received when we individually pulled the bytes.
data
属性包含字节的整数表示形式的数组。 您可能已经注意到, 72
, 105
,和33
对应于当我们单独拉字节我们收到的值。
Let’s try the toJSON()
method with tenZeroes
:
让我们用tenZeroes
尝试toJSON()
方法:
In the REPL you will see the following:
在REPL中,您将看到以下内容:
Output
{ type: 'Buffer', data: [
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
] }
The type
is the same as noted before. However, the data is now an array with ten zeroes.
type
与前面提到的相同。 但是,数据现在是具有十个零的数组。
Now that we’ve covered the main ways to read from a buffer, let’s look at how we modify a buffer’s contents.
既然我们已经介绍了从缓冲区读取数据的主要方法,那么让我们看一下如何修改缓冲区的内容。
There are many ways we can modify an existing buffer object. Similar to reading, we can modify buffer bytes individually using the array syntax. We can also write new contents to a buffer, replacing the existing data.
我们可以通过多种方式修改现有的缓冲区对象。 与读取类似,我们可以使用数组语法分别修改缓冲区字节。 我们还可以将新内容写入缓冲区,以替换现有数据。
Let’s begin by looking at how we can change individual bytes of a buffer. Recall our buffer variable hiBuf
, which contains the string Hi!
. Let’s change each byte so that it contains Hey
instead.
让我们从如何更改缓冲区的各个字节开始。 回忆我们的缓冲变量hiBuf
,它包含字符串Hi!
。 让我们更改每个字节,使其包含Hey
。
In the REPL, let’s first try setting the second element of hiBuf
to e
:
在REPL中,让我们首先尝试将hiBuf
的第二个元素设置为e
:
Now, let’s see this buffer as a string to confirm it’s storing the right data. Follow up by calling the toString()
method:
现在,让我们将该缓冲区视为一个字符串,以确认其存储了正确的数据。 通过调用toString()
方法进行后续操作:
It will be evaluated as:
它将被评估为:
Output
'H\u0000!'
We received that strange output because the buffer can only accept an integer value. We can’t assign it to the letter e
; rather, we have to assign it the number whose binary equivalent represents e
:
我们收到了奇怪的输出,因为缓冲区只能接受整数值。 我们不能将其分配给字母e
; 相反,我们必须为其分配与二进制等价的代表e
:
Now when we call the toString()
method:
现在,当我们调用toString()
方法时:
We get this output in the REPL:
我们在REPL中得到以下输出:
Output
'He!'
To change the last character in the buffer, we need to set the third element to the integer that corresponds to the byte for y
:
要更改缓冲区中的最后一个字符,我们需要将第三个元素设置为与y
字节对应的整数:
Let’s confirm by using the toString()
method once again:
让我们再次使用toString()
方法进行确认:
Your REPL will display:
您的REPL将显示:
Output
'Hey'
If we try to write a byte that’s outside the range of the buffer, it will be ignored and the contents of the buffer won’t change. For example, let’s try to set the non-existent fourth element of the buffer to o
:
如果我们尝试写一个超出缓冲区范围的字节,它将被忽略并且缓冲区的内容不会改变。 例如,让我们尝试将缓冲区不存在的第四个元素设置为o
:
We can confirm that the buffer is unchanged with the toString()
method:
我们可以使用toString()
方法确认缓冲区未更改:
The output is still:
输出仍然是:
Output
'Hey'
If we wanted to change the contents of the entire buffer, we can use the write()
method. The write()
method accepts a string that will replace the contents of a buffer.
如果我们想更改整个缓冲区的内容,可以使用write()
方法。 write()
方法接受一个将替换缓冲区内容的字符串。
Let’s use the write()
method to change the contents of hiBuf
back to Hi!
. In your Node.js shell, type the following command at the prompt:
让我们使用write()
方法将hiBuf
的内容hiBuf
回Hi!
。 在您的Node.js Shell中,在提示符下键入以下命令:
The write()
method returned 3
in the REPL. This is because it wrote three bytes of data. Each letter has one byte in size, since this buffer uses UTF-8 encoding, which uses a byte for each character. If the buffer used UTF-16 encoding, which has a minimum of two bytes per character, then the write()
function would have returned 6
.
write()
方法在REPL中返回3
。 这是因为它写入了三个字节的数据。 每个字母都有一个字节大小,因为此缓冲区使用UTF-8编码,每个字符使用一个字节。 如果缓冲区使用UTF-16编码(每个字符至少两个字节),则write()
函数将返回6
。
Now verify the contents of the buffer by using toString()
:
现在,使用toString()
验证缓冲区的内容:
The REPL will produce:
REPL将产生:
Output
'Hi!'
This is quicker than having to change each element byte-by-byte.
这比逐个字节地更改每个元素要快。
If you try to write more bytes than a buffer’s size, the buffer object will only accept what bytes fit. To illustrate, let’s create a buffer that stores three bytes:
如果尝试写入的字节数超过缓冲区的大小,则缓冲区对象将只接受适合的字节数。 为了说明这一点,让我们创建一个存储三个字节的缓冲区:
Now let’s attempt to write Cats
to it:
现在让我们尝试为它写Cats
:
When the write()
call is evaluated, the REPL returns 3
indicating only three bytes were written to the buffer. Now confirm that the buffer contains the first three bytes:
当评估write()
调用时,REPL返回3
指示仅三个字节被写入缓冲区。 现在确认缓冲区包含前三个字节:
The REPL returns:
REPL返回:
Output
'Cat'
The write()
function adds the bytes in sequential order, so only the first three bytes were placed in the buffer.
write()
函数按顺序添加字节,因此只有前三个字节被放置在缓冲区中。
By contrast, let’s make a Buffer
that stores four bytes:
相比之下,让我们创建一个存储四个字节的Buffer
:
Write the same contents to it:
向其中写入相同的内容:
Then add some new content that occupies less space than the original content:
然后添加一些比原始内容占用空间少的新内容:
Since buffers write sequentially, starting from 0
, if we print the buffer’s contents:
由于缓冲区从0
开始顺序写入,如果我们打印缓冲区的内容:
We’d be greeted with:
我们将受到欢迎:
Output
'Hits'
The first two characters are overwritten, but the rest of the buffer is untouched.
前两个字符被覆盖,但缓冲区的其余部分未触及。
Sometimes the data we want in our pre-existing buffer is not in a string but resides in another buffer object. In these cases, we can use the copy()
function to modify what our buffer is storing.
有时,我们想要在预先存在的缓冲区中的数据不在字符串中,而是位于另一个缓冲区对象中。 在这些情况下,我们可以使用copy()
函数来修改缓冲区存储的内容。
Let’s create two new buffers:
让我们创建两个新的缓冲区:
The wordsBuf
and catchphraseBuf
buffers both contain string data. We want to modify catchphraseBuf
so that it stores Nananana Turtle!
instead of Not sure Turtle!
. We’ll use copy()
to get Nananana
from wordsBuf
to catchphraseBuf
.
该wordsBuf
和catchphraseBuf
缓冲区都包含字符串数据。 我们要修改catchphraseBuf
使其存储Nananana Turtle!
而Not sure Turtle!
。 我们将使用copy()
获得Nananana
从wordsBuf
到catchphraseBuf
。
To copy data from one buffer to the other, we’ll use the copy()
method on the buffer that’s the source of the information. Therefore, as wordsBuf
has the string data we want to copy, we need to copy like this:
要将数据从一个缓冲区复制到另一个缓冲区,我们将在作为信息来源的缓冲区上使用copy()
方法。 因此,由于wordsBuf
具有要复制的字符串数据,因此我们需要像这样复制:
The target
parameter in this case is the catchphraseBuf
buffer.
在这种情况下, target
参数是catchphraseBuf
缓冲区。
When we enter that into the REPL, it returns 15
indicating that 15 bytes were written. The string Nananana
only uses 8 bytes of data, so we immediately know that our copy did not go as intended. Use the toString()
method to see the contents of catchphraseBuf
:
当我们将其输入REPL时,它返回15
表示已写入15个字节。 字符串Nananana
仅使用8个字节的数据,因此我们立即知道我们的副本未按预期进行。 使用toString()
方法查看catchphraseBuf
的内容:
The REPL returns:
REPL返回:
Output
'Banana Nananana!'
By default, copy()
took the entire contents of wordsBuf
and placed it into catchphraseBuf
. We need to be more selective for our goal and only copy Nananana
. Let’s re-write the original contents of catchphraseBuf
before continuing:
默认情况下, copy()
把全部内容wordsBuf
,把它变成catchphraseBuf
。 我们需要对我们的目标更具选择性,只复制Nananana
。 在继续之前,让我们重写catchphraseBuf
的原始内容:
The copy()
function has a few more parameters that allow us to customize what data is copied to the other buffer. Here’s a list of all the parameters of this function:
copy()
函数还有更多参数,这些参数使我们可以自定义将哪些数据复制到另一个缓冲区。 这是此函数的所有参数的列表:
target
- This is the only required parameter of copy()
. As we’ve seen from our previous usage, it is the buffer we want to copy to.
target
这是copy()
唯一需要的参数。 正如我们从以前的用法中看到的那样,它是我们要复制到的缓冲区。
targetStart
- This is the index of the bytes in the target buffer where we should begin copying to. By default it’s 0
, meaning it copies data starting at the beginning of the buffer.
targetStart
这是目标缓冲区中我们应该开始复制到的字节的索引。 默认情况下为0
,这意味着它将从缓冲区的开头开始复制数据。
sourceStart
- This is the index of the bytes in the source buffer where we should copy from.
sourceStart
这是应从中复制源缓冲区中字节的索引。
sourceEnd
- This is the index of the bytes in the source buffer where we should stop copying. By default, it’s the length of the buffer.
sourceEnd
这是我们应停止复制的源缓冲区中字节的索引。 默认情况下,它是缓冲区的长度。
So, to copy Nananana
from wordsBuf
into catchphraseBuf
, our target
should be catchphraseBuf
like before. The targetStart
would be 0
as we want Nananana
to appear at the beginning of catchphraseBuf
. The sourceStart
should be 7
as that’s the index where Nananana
begins in wordsBuf
. The sourceEnd
would continue to be the length of the buffers.
因此,复制Nananana
从wordsBuf
到catchphraseBuf
,我们的target
应该是catchphraseBuf
像以前一样。 该targetStart
将是0
,因为我们希望Nananana
出现之初catchphraseBuf
。 该sourceStart
应该是7
作为这也正是指数Nananana
始于wordsBuf
。 sourceEnd
将继续是缓冲区的长度。
At the REPL prompt, copy the contents of wordsBuf
like this:
在REPL提示符下,复制wordsBuf
的内容,如下所示:
The REPL confirms that 8
bytes have been written. Note how wordsBuf.length
is used as the value for the sourceEnd
parameter. Like arrays, the length
property gives us the size of the buffer.
REPL确认已写入8
个字节。 请注意wordsBuf.length
如何用作sourceEnd
参数的值。 像数组一样, length
属性为我们提供了缓冲区的大小。
Now let’s see the contents of catchphraseBuf
:
现在让我们看看catchphraseBuf
的内容:
The REPL returns:
REPL返回:
Output
'Nananana Turtle!'
Success! We were able to modify the data of catchphraseBuf
by copying the contents of wordsBuf
.
成功! 我们能够修改的数据catchphraseBuf
通过复制的内容wordsBuf
。
You can exit the Node.js REPL if you would like to do so. Note that all the variables that were created will no longer be available when you do:
您可以退出Node.js REPL。 请注意,执行以下操作后,所有创建的变量将不再可用:
In this tutorial, you learned that buffers are fixed-length allocations in memory that store binary data. You first created buffers by defining their size in memory and by initializing them with pre-existing data. You then read data from a buffer by examining their individual bytes and by using the toString()
and toJSON()
methods. Finally, you modified the data stored by a buffer by changing its individual bytes and by using the write()
and copy()
methods.
在本教程中,您了解到缓冲区是存储二进制数据的内存中的固定长度分配。 首先,通过定义缓冲区在内存中的大小并使用预先存在的数据对其进行初始化来创建缓冲区。 然后,您可以通过检查缓冲区的各个字节以及使用toString()
和toJSON()
方法来从缓冲区读取数据。 最后,通过更改缓冲区的各个字节以及使用write()
和copy()
方法来修改缓冲区存储的数据。
Buffers give you great insight into how binary data is manipulated by Node.js. Now that you can interact with buffers, you can observe the different ways character encoding affect how data is stored. For example, you can create buffers from string data that are not UTF-8 or ASCII encoding and observe their difference in size. You can also take a buffer with UTF-8 and use toString()
to convert it to other encoding schemes.
缓冲区使您可以深入了解Node.js如何处理二进制数据。 现在,您可以与缓冲区交互,您可以观察字符编码影响数据存储方式的不同方式。 例如,您可以使用非UTF-8或ASCII编码的字符串数据创建缓冲区,并观察它们的大小差异。 您也可以使用UTF-8缓冲区,并使用toString()
将其转换为其他编码方案。
To learn about buffers in Node.js, you can read the Node.js documentation on the Buffer
object. If you’d like to continue learning Node.js, you can return to the How To Code in Node.js series, or browse programming projects and setups on our Node topic page.
要了解Node.js中的缓冲区,您可以阅读Buffer
对象上的Node.js文档 。 如果您想继续学习Node.js,可以返回“ 如何在Node.js中编码”系列 ,或者在Node主题页面上浏览编程项目和设置。
翻译自: https://www.digitalocean.com/community/tutorials/using-buffers-in-node-js
node缓冲区