readable.read([size])


readable.read() 方法从内部缓冲区读取数据并返回。如果没有可读取的数据,则返回 null。默认情况下,数据会作为 Buffer 对象返回,除非通过 readable.setEncoding() 方法指定了编码,或者流正在以对象模式运行。

【The readable.read() method reads data out of the internal buffer and returns it. If no data is available to be read, null is returned. By default, the data is returned as a Buffer object unless an encoding has been specified using the readable.setEncoding() method or the stream is operating in object mode.】

可选的 size 参数指定要读取的字节数。如果没有足够的 size 字节可供读取,将返回 null,_除非_流已结束,在这种情况下,将返回内部缓冲区中剩余的所有数据。

【The optional size argument specifies a specific number of bytes to read. If size bytes are not available to be read, null will be returned unless the stream has ended, in which case all of the data remaining in the internal buffer will be returned.】

如果未指定 size 参数,将返回内部缓冲区中包含的所有数据。

【If the size argument is not specified, all of the data contained in the internal buffer will be returned.】

size 参数必须小于或等于 1 GiB。

【The size argument must be less than or equal to 1 GiB.】

readable.read() 方法应仅在处于暂停模式的 Readable 流上调用。在流动模式下,readable.read() 会自动调用,直到内部缓冲区完全清空。

【The readable.read() method should only be called on Readable streams operating in paused mode. In flowing mode, readable.read() is called automatically until the internal buffer is fully drained.】

const readable = getReadableStreamSomehow();

// 'readable' may be triggered multiple times as data is buffered in
readable.on('readable', () => {
  let chunk;
  console.log('Stream is readable (new data received in buffer)');
  // Use a loop to make sure we read all currently available data
  while (null !== (chunk = readable.read())) {
    console.log(`Read ${chunk.length} bytes of data...`);
  }
});

// 'end' will be triggered once when there is no more data available
readable.on('end', () => {
  console.log('Reached end of stream.');
}); 

每次调用 readable.read() 都会返回一块数据或 null,表示此刻没有更多数据可供读取。这些数据块不会自动拼接。由于一次 read() 调用不会返回所有数据,因此可能需要使用 while 循环来持续读取数据块,直到获取所有数据。在读取大文件时,.read() 可能会暂时返回 null,表示它已消耗所有缓冲的内容,但可能还有更多数据尚未缓冲。在这种情况下,一旦缓冲区中有更多数据,就会触发一个新的 'readable' 事件,而 'end' 事件则表示数据传输结束。

【Each call to readable.read() returns a chunk of data or null, signifying that there's no more data to read at that moment. These chunks aren't automatically concatenated. Because a single read() call does not return all the data, using a while loop may be necessary to continuously read chunks until all data is retrieved. When reading a large file, .read() might return null temporarily, indicating that it has consumed all buffered content but there may be more data yet to be buffered. In such cases, a new 'readable' event is emitted once there's more data in the buffer, and the 'end' event signifies the end of data transmission.】

因此,要从 readable 中读取文件的全部内容,就有必要在多个 'readable' 事件中收集数据块:

【Therefore to read a file's whole contents from a readable, it is necessary to collect chunks across multiple 'readable' events:】

const chunks = [];

readable.on('readable', () => {
  let chunk;
  while (null !== (chunk = readable.read())) {
    chunks.push(chunk);
  }
});

readable.on('end', () => {
  const content = chunks.join('');
}); 

Readable 流在对象模式下,无论 size 参数的值是多少,从调用 readable.read(size) 返回的总是单个项目。

【A Readable stream in object mode will always return a single item from a call to readable.read(size), regardless of the value of the size argument.】

如果 readable.read() 方法返回一段数据,也会触发 'data' 事件。

【If the readable.read() method returns a chunk of data, a 'data' event will also be emitted.】

'end' 事件被触发后调用 stream.read([size]) 将返回 null。不会引发运行时错误。

【Calling stream.read([size]) after the 'end' event has been emitted will return null. No runtime error will be raised.】