>  기사  >  웹 프론트엔드  >  Node.js에서 스트림 사용의 이점

Node.js에서 스트림 사용의 이점

PHPz
PHPz원래의
2024-07-17 12:26:50527검색

Benefícios do Uso de Streams em Node.js

소개

대량의 데이터를 처리할 때 Node.js에서 스트림을 사용하면 성능과 효율성 측면에서 엄청난 이점을 얻을 수 있습니다. 스트림을 사용하면 파일이 메모리에 완전히 로드되는 것을 방지하여 데이터를 연속적으로 청크로 처리할 수 있습니다. 이 기사에서는 대용량 텍스트 파일을 효율적으로 변환하는 방법을 보여 주는 실제 예를 사용하여 스트림 사용의 이점을 살펴봅니다.

스트림이란 무엇입니까?

스트림은 모든 것을 메모리에 한 번에 로드하는 대신 데이터를 청크로 처리할 수 있도록 하는 Node.js의 추상화입니다. Node.js에는 네 가지 주요 스트림 유형이 있습니다.

  1. 읽기 가능: 데이터를 읽을 수 있는 곳에서 스트리밍합니다.
  2. 쓰기 가능: 데이터를 쓸 수 있는 스트림.
  3. 이중: 읽기 및 쓰기가 모두 가능한 스트림
  4. 변형: 데이터가 통과할 때 데이터를 수정하거나 변환할 수 있는 스트림

스트림의 이점

1. 메모리 효율성

스트림을 사용하면 데이터가 청크로 처리되므로 전체 파일을 메모리에 로드할 필요가 없습니다. 이는 메모리 문제를 방지하고 시스템 성능을 향상시키므로 대용량 파일에 매우 중요합니다.

2. 실시간 데이터 처리

스트림을 사용하면 지속적인 데이터 처리가 가능합니다. 예를 들어, 다음 데이터를 수신하는 동안 첫 번째 데이터 청크 처리를 시작할 수 있으므로 총 처리 시간이 단축됩니다.

3. 대응성 유지

Node.js 이벤트 루프를 차단하지 않음으로써 스트림은 I/O 집약적인 작업 중에도 애플리케이션의 응답성을 유지하는 데 도움이 됩니다.

실제 사례

테스트 파일 생성

시작하기 전에 테스트용으로 큰 텍스트 파일을 만들어 보겠습니다. 다음 Python 스크립트를 사용하여 10GB 파일을 생성할 수 있습니다.

# generator.py

# Define o tamanho do arquivo em bytes (10GB)
file_size = 10000 * 1024 * 1024  # 10 GB

# Linha que será escrita repetidas vezes no arquivo
line = "This is a line of text to be transformed. Adding more text to increase the size of each line.\n"

# Calcula o número de linhas necessárias para preencher o arquivo
num_lines = file_size // len(line)

# Cria e escreve o arquivo
file_path = "large-input.txt"
with open(file_path, "w") as file:
    for _ in range(num_lines):
        file.write(line)

print(f"File created successfully at {file_path}")

위 스크립트를 실행하려면 Generator.py로 저장하고 다음 명령을 사용하여 실행하세요.

python3 generator.py

스트림을 사용하여 파일 변환

다음은 Large-input.txt의 내용을 대문자로 변환하고 결과를 Large-output.txt에 저장하는 Node.js의 코드입니다. 또한 10%마다 진행률과 총 처리 시간을 표시합니다.

// src/index.js

const fs = require('fs');
const { Transform } = require('stream');
const { performance } = require('perf_hooks');

// Caminho para o arquivo de entrada e saída
const inputFile = 'large-input.txt';
const outputFile = 'large-output.txt';

// Cria um Readable Stream a partir do arquivo de entrada
const readableStream = fs.createReadStream(inputFile, { encoding: 'utf8' });

// Cria um Writable Stream para o arquivo de saída
const writableStream = fs.createWriteStream(outputFile);

// Variáveis para rastreamento de progresso
let totalSize = 0;
let processedSize = 0;
let lastLoggedProgress = 0;
const startTime = performance.now();
let processedLines = 0;

fs.stat(inputFile, (err, stats) => {
  if (err) {
    console.error('Erro ao obter informações do arquivo:', err);
    return;
  }
  totalSize = stats.size;

  // Pipe o Readable Stream para o Transform Stream e depois para o Writable Stream
  readableStream
    .pipe(
      new Transform({
        transform(chunk, encoding, callback) {
          processedSize += chunk.length;
          processedLines += chunk.toString().split('\n').length - 1;

          // Converte o chunk de dados para letras maiúsculas
          const upperCaseChunk = chunk.toString().toUpperCase();

          // Chama o callback com o chunk transformado
          callback(null, upperCaseChunk);

          // Log de progresso
          const progress = (processedSize / totalSize) * 100;

          if (progress >= lastLoggedProgress + 10) {
            console.log(
              `Progresso: ${Math.floor(progress)}%, Linhas processadas: ${processedLines}`
            );
            lastLoggedProgress = Math.floor(progress);
          }
        },
      })
    )
    .pipe(writableStream)
    .on('finish', () => {
      const endTime = performance.now();
      const timeTaken = ((endTime - startTime) / 1000).toFixed(2);
      console.log('Transformação completa e arquivo salvo.');
      console.log(`Total de linhas processadas: ${processedLines}`);
      console.log(`Tempo total: ${timeTaken} segundos`);
    })
    .on('error', (err) => {
      console.error('Erro durante a transformação:', err);
    });
});

이 접근 방식의 이점

  1. 메모리 효율성: 스트림을 사용하면 전체 파일을 메모리에 로드하지 않고도 대용량 데이터를 처리할 수 있어 메모리 오버플로를 방지하고 성능을 향상시킬 수 있습니다.
  2. 최고의 성능: 연속적인 청크로 데이터를 처리하면 파일이 완전히 로드될 때까지 기다리지 않고 즉시 처리를 시작할 수 있습니다.
  3. 실시간 피드백: 실시간 진행 상황 표시를 통해 처리 진행 상황을 명확하게 확인할 수 있어 모니터링이 가능하고 필요한 경우 빠른 개입이 가능합니다.

결론

스트림은 대량의 데이터를 조작하기 위한 Node.js의 강력한 도구입니다. 스트림을 사용하면 파일을 효율적으로 처리하여 애플리케이션의 응답성을 유지하고 메모리 문제를 방지할 수 있습니다. 위의 예는 스트림을 사용하여 대용량 텍스트 파일을 변환하고 프로세스의 진행 상황과 총 시간을 표시하는 방법을 보여줍니다.

자세한 내용과 전체 코드에 액세스하려면 내 GitHub 저장소를 방문하세요.

위 내용은 Node.js에서 스트림 사용의 이점의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:n X 확률 승수다음 기사:n X 확률 승수