Node.js でストリームを使用する利点

PHPz
リリース: 2024-07-17 12:26:50
オリジナル
533 人が閲覧しました

Benefícios do Uso de Streams em Node.js

導入

大量のデータを処理する場合、Node.js でストリームを使用すると、パフォーマンスと効率の点で大きな利点が得られます。ストリームを使用すると、データを連続的にチャンク単位で処理できるため、メモリへのファイルの完全なロードが回避されます。この記事では、実際的な例を使用して、大きなテキスト ファイルを効率的に変換する方法を示しながら、ストリームを使用する利点について説明します。

ストリームとは何ですか?

ストリームは、一度にすべてをメモリにロードするのではなく、データをチャンクで処理できるようにする Node.js の抽象化です。 Node.js には主に 4 つのタイプのストリームがあります:

  1. 読み取り可能: データを読み取ることができるストリーム。
  2. 書き込み可能: データを書き込むことができるストリーム。
  3. 二重: 読み取りと書き込みの両方が可能なストリーム。
  4. Transform: データが通過するときにデータを変更または変換できるストリーム。

ストリームの利点

1. メモリ効率

ストリームを使用すると、データはチャンク単位で処理されます。つまり、ファイル全体をメモリにロードする必要はありません。これはメモリの問題を回避し、システムのパフォーマンスを向上させるため、大きなファイルの場合に非常に重要です。

2. リアルタイムデータ処理

ストリームにより、継続的なデータ処理が可能になります。たとえば、次のデータを受信して​​いる間に最初のデータ チャンクの処理を開始できるため、合計の処理時間が短縮されます。

3. 応答性の維持

ストリームは Node.js イベント ループをブロックしないため、I/O 集中型の操作中であってもアプリケーションの応答性を維持できます。

実践例

テストファイルの生成

始める前に、テスト用に大きなテキスト ファイルを作成しましょう。次の Python スクリプトを使用して、10 GB のファイルを生成できます:

# 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 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート