>  기사  >  웹 프론트엔드  >  Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.

Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.

青灯夜游
青灯夜游앞으로
2021-12-20 11:13:082201검색

이 글은 Nodejs의 스트림 모듈에 대한 자세한 이해를 제공하고 스트림의 개념과 사용법을 소개하는 것이 모든 사람에게 도움이 되기를 바랍니다.

Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.

stream 모듈은 Node의 매우 핵심적인 모듈입니다. fs, http 등과 같은 다른 모듈은 stream 모듈의 인스턴스를 기반으로 합니다.

대부분의 프론트엔드 초보자들은 Node를 처음 시작할 때 아직까지 스트림의 개념과 사용법에 대한 명확한 이해가 부족한 상태입니다. 왜냐하면 그 앞에 "스트림" 처리와 관련된 응용프로그램이 거의 없는 것 같기 때문입니다. -일을 끝내세요.

1.플로우란?

흐름이라는 간단한 단어 하나로 우리는 물의 흐름, 흐름 등의 개념을 쉽게 가질 수 있습니다.

공식 정의: Stream은 Node.js에서 스트림 데이터를 처리하는 데 사용되는 추상 인터페이스입니다.

공식 정의에서 보면 다음과 같습니다.

  • Stream은 Node Tool에서 제공하는 데이터 처리 방법입니다.
  • Stream은 Node의 추상 인터페이스

정확하게 이해하면 스트림은 애플리케이션에서 데이터를 전송하는 수단인 데이터 스트림으로 이해될 수 있습니다. 스트림은 시작점과 끝점이 있는 정렬된 데이터 흐름입니다. 数据流,它是一种用来传输数据的手段,在一个应用程序中,流,是一种有序的,有起点和终点的数据流。

造成我们对stream流不太好的理解的主要原因就是,它是一种抽象的概念。

2. 流,的具体使用场景

为了让我们能够清楚的理解stream模块,我们首先来以具体的应用场景来说明stream模块有哪些实际应用之处。

stream流,在Node中主要应用在大量数据处理的需求上,如fs对大文件的读取和写入、http请求响应、文件的压缩、数据的加密/解密等应用。

Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.

我们以上面的图片说明流的使用,水桶可以理解为数据源,水池可以理解为数据目标,中间连接的管道,我们可以理解为数据流,通过数据流管道,数据从数据源流向数据目标。

3. 流的分类

在Node中,流被分为4类:可读流,可写流,双工流,转换流。

  • Writable: 可以写入数据的流
  • Readable: 可以从中读取数据的流
  • DuplexReadable 和 Writable 的流
  • Transform: 可以在写入和读取数据时修改或转换数据的 Duplex 流

所有的流都是 EventEmitter 的实例。即我们可以通过事件机制监听数据流的变化。

4. 数据模式和缓存区

在深入学习4类流的具体使用之前,我们需要理解两个概念数据模式缓存区,有助于我们在接下来流的学习中更好的理解。

4.1 数据模式

Node.js API 创建的所有流都只对字符串和 Buffer(或 Uint8Array)对象进行操作。

4.2 缓存区

Writable和 Readable

우리가 스트림을 잘 이해하지 못하는 가장 큰 이유는 그것이 추상적인 개념이기 때문입니다. 🎜🎜2. 스트림의 특정 사용 시나리오🎜🎜스트림 모듈을 명확하게 이해하기 위해 먼저 특정 응용 프로그램 시나리오를 사용하여 스트림 모듈의 실제 응용 프로그램을 설명합니다. 🎜🎜stream은 Node에서 주로 대량의 데이터 처리 요구 사항(예: 대용량 파일 읽기 및 쓰기, http 요청 응답, 파일 압축, 데이터 암호화/복호화 및 기타 응용 프로그램)에 사용됩니다. . 🎜🎜Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.🎜🎜us 위 그림은 스트림의 용도를 보여줍니다. 버킷은 데이터 소스로 이해하고, 풀은 데이터 대상으로 이해하고, 중간에 연결하는 파이프는 data.Stream으로 이해되는 데이터는 데이터 흐름 파이프라인을 통해 데이터 소스에서 데이터 대상으로 흐릅니다. 🎜🎜3. 스트림 분류🎜🎜Node에서 스트림은 읽기 가능한 스트림, 쓰기 가능한 스트림, 이중 스트림, 변환 스트림의 4가지 범주로 나뉩니다. 🎜🎜🎜쓰기 가능🎜: 데이터를 쓸 수 있는 스트림🎜🎜읽기 가능🎜: 데이터를 읽을 수 있는 스트림🎜🎜이중🎜: 읽기 가능쓰기 가능 코드 > 스트림🎜🎜Transform🎜: 작성하고 읽을 수 있음 데이터를 수정하거나 변환하는 이중 스트림 🎜🎜🎜모든 스트림은 EventEmitter🎜 인스턴스. 즉, 이벤트 메커니즘을 통해 데이터 흐름의 변화를 모니터링할 수 있습니다. 🎜🎜4. 데이터 모드 및 캐시 영역 🎜🎜4가지 유형의 스트림의 구체적인 사용법을 자세히 알아보기 전에 데이터 모드버퍼 영역)을 이해해야 합니다. > 도움이 됩니다. 다음 학습 흐름에서 더 잘 이해하는 데 도움이 될 것입니다. 🎜🎜4.1 데이터 모드🎜🎜Node.js API로 생성된 모든 스트림은 문자열에서만 작동합니다. > Buffer(또는 Uint8Array) 객체로 작동합니다. 🎜🎜4.2 캐시🎜🎜쓰기 가능읽기 가능 스트림은 둘 다입니다. 내부 버퍼에 데이터를 저장합니다. 🎜

버퍼링할 수 있는 데이터의 양은 스트림 생성자에 전달된 highWaterMark 옵션에 따라 다릅니다. 일반 스트림의 경우 highWaterMark 옵션은 총 바이트 수를 지정합니다. ;객체 모드에서 작동하는 스트림의 경우 highWaterMark 옵션은 총 객체 수를 지정합니다. highWaterMark 选项, 对于普通的流,highWaterMark 选项指定字节的总数;对于在对象模式下操作的流,highWaterMark选项指定对象的总数。

highWaterMark 选项是阈值,而不是限制:它规定了流在停止请求更多数据之前缓冲的数据量。

当实现调用 stream.push(chunk) 时,数据缓存在 Readable 流中。 如果流的消费者没有调用 stream.read(),则数据会一直驻留在内部队列中,直到被消费。

一旦内部读取缓冲区的总大小达到 highWaterMark 指定的阈值,则流将暂时停止从底层资源读取数据,直到可以消费当前缓冲的数据

当重复调用 writable.write(chunk) 方法时,数据会缓存在 Writable 流中。

5. 可读流

5.1 流读取的流动与暂停

Readable

highWaterMark 옵션은 한계가 아니라 임계값입니다. 이는 스트림이 추가 데이터 요청을 중지하기 전에 버퍼링하는 데이터의 양을 나타냅니다.
  • 구현이 stream.push(chunk)

    캐시된 경우 읽기 가능 스트림에 있습니다. 스트림 소비자가 stream.read()

    , 데이터는 항상 상주합니다. 소비될 때까지 내부 대기열에 남아 있습니다.
  • 내부 읽기 버퍼의 전체 크기가 highWaterMark에 지정된 임계값에 도달하면 스트림은 현재 버퍼링된 데이터가 소비될 수 있을 때까지 기본 리소스에서 데이터 읽기를 일시적으로 중지합니다.

    반복적으로 호출되는 경우 writable.write(chunk)
  • 메서드를 사용하면 데이터가 쓰기 가능 스트림에 캐시됩니다.
  • 5. 읽기 가능한 스트림

    • 5.1 스트림 읽기를 위한 흐름 및 일시 중지
    • 읽기 가능 스트림은 흐름 및 일시 중지의 두 가지 모드 중 하나로 효과적으로 실행됩니다.
  • Flow 모드: 시스템의 하위 계층에서 데이터를 읽고 이를 캐시 영역으로 push()합니다. highWaterMark에 도달한 후 push()는 false를 반환하고 리소스는 캐시 영역으로의 흐름을 중지합니다. 데이터 이벤트는 데이터를 소비하기 위해 트리거됩니다.

    • Pause 모드: 모든 읽기 가능한 스트림은 Paused 일시 중지 모드에서 시작하며, 스트림에서 데이터를 읽으려면 stream.read() 메서드를 명시적으로 호출해야 합니다. 데이터가 버퍼 영역에 도달할 때마다 읽기 가능 이벤트가 트리거됩니다. 즉, 모든 push()가 읽기 가능 이벤트를 트리거합니다.
  • 일시 중지 모드를 흐름 모드로 전환하는 방법:

데이터 이벤트 핸들 추가 stream.resume() 메서드 호출

stream.pipe() 메서드를 호출하여 데이터를 Writable로 전송

흐름 모드 일시 정지 모드로 전환하는 방법:

파이프라인 대상이 없으면 stream.pause() 메서드를 호출합니다.

파이프라인 대상이 있으면 모두 삭제하세요. stream.unpipe() 메서드를 호출하여 여러 파이프라인 대상을 제거할 수 있습니다.

5.2 읽기 가능한 스트림의 일반적인 예

import path from 'path';
import fs, { read } from 'fs';

const filePath = path.join(path.resolve(), 'files', 'text.txt');

const readable = fs.createReadStream(filePath);
// 如果使用 readable.setEncoding() 方法为流指定了默认编码,则监听器回调将把数据块作为字符串传入;否则数据将作为 Buffer 传入。
readable.setEncoding('utf8');
let str = '';

readable.on('open', (fd) => {
  console.log('开始读取文件')
})
// 每当流将数据块的所有权移交给消费者时,则会触发 'data' 事件
readable.on('data', (data) => {
  str += data;
  console.log('读取到数据')
})
// 方法将导致处于流动模式的流停止触发 'data' 事件,切换到暂停模式。 任何可用的数据都将保留在内部缓冲区中。
readable.pause();
// 方法使被显式暂停的 Readable 流恢复触发 'data' 事件,将流切换到流动模式。
readable.resume();
// 当调用 stream.pause() 并且 readableFlowing 不是 false 时,则会触发 'pause' 事件。
readable.on('pause', () => {
  console.log('读取暂停')
})
// 当调用 stream.resume() 并且 readableFlowing 不是 true 时,则会触发 'resume' 事件。
readable.on('resume', () => {
  console.log('重新流动')
})
// 当流中没有更多数据可供消费时,则会触发 'end' 事件。
readable.on('end', () => {
  console.log('文件读取完毕');
})
// 当流及其任何底层资源(例如文件描述符)已关闭时,则会触发 'close' 事件。
readable.on('close', () => {
  console.log('关闭文件读取')
})
// 将 destWritable 流绑定到 readable,使其自动切换到流动模式并将其所有数据推送到绑定的 Writable。 数据流将被自动管理
readable.pipe(destWriteable)
// 如果底层流由于底层内部故障而无法生成数据,或者当流实现尝试推送无效数据块时,可能会发生这种情况。
readable.on('error', (err) => {
  console.log(err)
  console.log('文件读取发生错误')
})
6. 쓰기 가능한 스트림

🎜🎜🎜6.1 쓰기 가능한 스트림의 흐름과 일시 중지🎜🎜🎜🎜쓰기 가능한 스트림과 읽기 가능한 스트림은 비교적 유사합니다. 데이터 그럴 때 쓰기 속도가 느리거나 쓰기가 일시 중단되면 데이터 흐름이 캐시 영역에 캐시됩니다. 🎜🎜생산자가 너무 빨리 쓰면 큐 풀이 대기열이 해제되면 "역압력"이 나타납니다. 대기열이 해제되면 생산을 재개하기 위해 쓰기 가능한 스트림이 생산자를 일시 중지하라는 지시를 받아야 합니다. . 🎜🎜🎜🎜6.2 쓰기 가능한 스트림 예제🎜🎜🎜
import path from 'path';
import fs, { read } from 'fs';

const filePath = path.join(path.resolve(), 'files', 'text.txt');
const copyFile = path.join(path.resolve(), 'files', 'copy.txt');

let str = '';
// 创建可读流
const readable = fs.createReadStream(filePath);
// 如果使用 readable.setEncoding() 方法为流指定了默认编码
readable.setEncoding('utf8');

// 创建可写流
const wirteable = fs.createWriteStream(copyFile);
// 编码
wirteable.setDefaultEncoding('utf8');

readable.on('open', (fd) => {
  console.log('开始读取文件')
})
// 每当流将数据块的所有权移交给消费者时,则会触发 'data' 事件
readable.on('data', (data) => {
  str += data;
  console.log('读取到数据');

  // 写入
  wirteable.write(data, 'utf8');
})

wirteable.on('open', () => {
  console.log('开始写入数据')
})
// 如果对 stream.write(chunk) 的调用返回 false,则 'drain' 事件将在适合继续将数据写入流时触发。
// 即生产数据的速度大于写入速度,缓存区装满之后,会暂停生产着从底层读取数据
// writeable缓存区释放之后,会发送一个drain事件让生产者继续读取
wirteable.on('drain', () => {
  console.log('继续写入')
})
// 在调用 stream.end() 方法之后,并且所有数据都已刷新到底层系统,则触发 'finish' 事件。
wirteable.on('finish', () => {
  console.log('数据写入完毕')
})

readable.on('end', () => {
  // 数据读取完毕通知可写流
  wirteable.end()
})
// 当在可读流上调用 stream.pipe() 方法将此可写流添加到其目标集时,则触发 'pipe' 事件。
// readable.pipe(destWriteable)
wirteable.on('pipe', () => {
  console.log('管道流创建')
})

wirteable.on('error', () => {
  console.log('数据写入发生错误')
})
🎜노드 관련 지식을 더 보려면 🎜nodejs 튜토리얼🎜을 방문하세요! ! 🎜

위 내용은 Nodejs의 핵심 모듈인 스트림 모듈(사용 방법 참조)에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제