node缓冲区_在Node.js中使用缓冲区

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计划的一部分。

介绍 (Introduction)

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类来处理二进制数据。

先决条件 (Prerequisites)

第1步-创建缓冲区 (Step 1 — Creating a Buffer)

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命令:

  • 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个字节,则可以在控制台中输入以下内容:

  • const firstBuf = Buffer.alloc(1024);

    const firstBuf = Buffer.alloc(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 1s instead of 0s, 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 1s:

在您的终端中,在REPL提示符下创建一个新缓冲区,该缓冲区充满1 s:

  • const filledBuf = Buffer.alloc(1024, 1);

    const filledBuf = Buffer.alloc(1024,1);

We just created a new buffer object that references a space in memory that stores 1KB of 1s. 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字符:

  • const asciiBuf = Buffer.alloc(5, 'a', 'ascii');

    const asciiBuf = Buffer.alloc(5,'a','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-8utf8

  • UTF-16, represented as utf-16le or utf16le

    UTF-16 ,表示为utf-16leutf16le

  • UCS-2, represented as ucs-2 or ucs2

    UCS-2 ,表示为ucs-2ucs2

  • Base64, represented as base64

    Base64 ,表示为base64

  • Hexadecimal, represented as hex

    十六进制 ,表示为hex

  • ISO/IEC 8859-1, represented as latin1 or binary

    ISO / IEC 8859-1 ,表示为latin1binary

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.

    整数数组:整数值可以在0255之间。

  • An ArrayBuffer: This is a JavaScript object that stores a fixed length of bytes.

    ArrayBuffer :这是一个JavaScript对象,用于存储固定长度的字节。

  • A string.

    一个字符串。
  • Another buffer.

    另一个缓冲区。
  • 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如何将对象转换为原始数据类型: booleannullundefinednumberstringsymbol 。 您可以在MozillaJavaScript 文档中阅读有关符号的更多信息。

Let’s see how we can create a buffer from a string. In the Node.js prompt, enter this:

让我们看看如何从字符串创建缓冲区。 在Node.js提示中,输入以下内容:

  • const stringBuf = Buffer.from('My name is Paul');

    const stringBuf = Buffer.from('我的名字是Paul');

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 。 让我们从之前创建的另一个缓冲区中创建一个新缓冲区:

  • const asciiCopy = Buffer.from(asciiBuf);

    const asciiCopy = Buffer.from(asciiBuf);

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.

既然我们具有创建缓冲区的经验,那么我们就可以深入研究读取其数据的示例。

步骤2 —从缓冲区读取 (Step 2 — Reading from a Buffer)

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中的字符串创建一个缓冲区来看看它的外观:

  • const hiBuf = Buffer.from('Hi!');

    const hiBuf = Buffer.from('Hi!');

Now let’s read the first byte of the buffer:

现在让我们读取缓冲区的第一个字节:

  • hiBuf[0];

    hiBuf [0];

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.

注意 :字节的值可以是0255之间的数字。 一个字节是8位的序列。 位是二进制的,因此只能具有两个值之一: 01 。 如果我们有一个8位的序列,每位有两个可能的值,那么一个字节最多有2个可能的值。 最多可计算256个值。 由于我们从零开始计数,因此我们的最高数为255。

Let’s do the same for the second byte. Enter the following in the REPL:

让我们对第二个字节做同样的事情。 在REPL中输入以下内容:

  • hiBuf[1];

    hiBuf [1];

The REPL returns 105, which represents the lowercase i.

REPL返回105 ,代表小写字母i

Finally, let’s get the third character:

最后,让我们获得第三个字符:

  • hiBuf[2];

    hiBuf [2];

You will see 33 displayed in the REPL, which corresponds to !.

您将看到REPL中显示33 ,它对应于!

Let’s try to retrieve a byte from an invalid index:

让我们尝试从无效索引中检索一个字节:

  • hiBuf[3];

    hiBuf [3];

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:

在提示中,输入:

  • hiBuf.toString();

    hiBuf.toString();

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个字节:

  • const tenZeroes = Buffer.alloc(10);

    const tenZeroes = Buffer.alloc(10);

Now, let’s use the toString() method:

现在,让我们使用toString()方法:

  • tenZeroes.toString();

    tenZeroes.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.

字符串\u0000NULL的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在提示符下输入以下内容:

  • hiBuf.toString('hex');

    hiBuf.toString('hex');

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:

让我们重新使用hiBuftenZeroes缓冲区来练习使用toJSON() 。 在提示符下,输入:

  • hiBuf.toJSON();

    hiBuf.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属性包含字节的整数表示形式的数组。 您可能已经注意到, 72105 ,和33对应于当我们单独拉字节我们收到的值。

Let’s try the toJSON() method with tenZeroes:

让我们用tenZeroes尝试toJSON()方法:

  • tenZeroes.toJSON();

    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.

既然我们已经介绍了从缓冲区读取数据的主要方法,那么让我们看一下如何修改缓冲区的内容。

步骤3 —修改缓冲区 (Step 3 — Modifying a Buffer)

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

  • hiBuf[1] = 'e';

    hiBuf [1] ='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()方法进行后续操作:

  • hiBuf.toString();

    hiBuf.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

  • hiBuf[1] = 101;

    hiBuf [1] = 101;

Now when we call the toString() method:

现在,当我们调用toString()方法时:

  • hiBuf.toString();

    hiBuf.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字节对应的整数:

  • hiBuf[2] = 121;

    hiBuf [2] = 121;

Let’s confirm by using the toString() method once again:

让我们再次使用toString()方法进行确认:

  • hiBuf.toString();

    hiBuf.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

  • hiBuf[3] = 111;

    hiBuf [3] = 111;

We can confirm that the buffer is unchanged with the toString() method:

我们可以使用toString()方法确认缓冲区未更改:

  • hiBuf.toString();

    hiBuf.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的内容hiBufHi! 。 在您的Node.js Shell中,在提示符下键入以下命令:

  • hiBuf.write('Hi!');

    hiBuf.write('嗨!');

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()验证缓冲区的内容:

  • hiBuf.toString();

    hiBuf.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:

如果尝试写入的字节数超过缓冲区的大小,则缓冲区对象将只接受适合的字节数。 为了说明这一点,让我们创建一个存储三个字节的缓冲区:

  • const petBuf = Buffer.alloc(3);

    const petBuf = Buffer.alloc(3);

Now let’s attempt to write Cats to it:

现在让我们尝试为它写Cats

  • petBuf.write('Cats');

    petBuf.write('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指示仅三个字节被写入缓冲区。 现在确认缓冲区包含前三个字节:

  • petBuf.toString();

    petBuf.toString();

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

  • const petBuf2 = Buffer.alloc(4);

    const petBuf2 = Buffer.alloc(4);

Write the same contents to it:

向其中写入相同的内容:

  • petBuf2.write('Cats');

    petBuf2.write('Cats');

Then add some new content that occupies less space than the original content:

然后添加一些比原始内容占用空间少的新内容:

  • petBuf2.write('Hi');

    petBuf2.write('Hi');

Since buffers write sequentially, starting from 0, if we print the buffer’s contents:

由于缓冲区从0开始顺序写入,如果我们打印缓冲区的内容:

  • petBuf2.toString();

    petBuf2.toString();

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:

让我们创建两个新的缓冲区:

  • const wordsBuf = Buffer.from('Banana Nananana');

    const wordsBuf = Buffer.from('Banana Nananana');
  • const catchphraseBuf = Buffer.from('Not sure Turtle!');

    const catchphraseBuf = Buffer.from('不确定Turtle!');

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.

wordsBufcatchphraseBuf缓冲区都包含字符串数据。 我们要修改catchphraseBuf使其存储Nananana Turtle!Not sure Turtle! 。 我们将使用copy()获得NanananawordsBufcatchphraseBuf

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具有要复制的字符串数据,因此我们需要像这样复制:

  • wordsBuf.copy(catchphraseBuf);

    wordsBuf.copy(catchphraseBuf);

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的内容:

  • catchphraseBuf.toString();

    catchphraseBuf.toString();

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的原始内容:

  • catchphraseBuf.write('Not sure Turtle!');

    catchphraseBuf.write('不确定Turtle!');

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.

因此,复制NanananawordsBufcatchphraseBuf ,我们的target应该是catchphraseBuf像以前一样。 该targetStart将是0 ,因为我们希望Nananana出现之初catchphraseBuf 。 该sourceStart应该是7作为这也正是指数Nananana始于wordsBufsourceEnd将继续是缓冲区的长度。

At the REPL prompt, copy the contents of wordsBuf like this:

在REPL提示符下,复制wordsBuf的内容,如下所示:

  • wordsBuf.copy(catchphraseBuf, 0, 7, wordsBuf.length);

    wordsBuf.copy(catchphraseBuf,0,7,wordsBuf.length);

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的内容:

  • catchphraseBuf.toString();

    catchphraseBuf.toString();

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。 请注意,执行以下操作后,所有创建的变量将不再可用:

  • .exit

    。出口

结论 (Conclusion)

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缓冲区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值