目次
1. ノードでのファイルの読み取りと書き込み
1.2 ストリーム ファイルの読み取りと書き込み
2. ノード ファイルの読み取りおよび書き込み RAM および Blob サイズの制限
2.2 分割読み取り
3. その他
3.1 ブラウザ側での大きなファイルの読み書きの拡張
3.2 请求静态资源大文件
ホームページ ウェブフロントエンド jsチュートリアル Nodejs が大きなファイルを読み書きする方法の簡単な分析

Nodejs が大きなファイルを読み書きする方法の簡単な分析

Sep 28, 2022 pm 08:09 PM
nodejs node

Nodejs が大きなファイルを読み書きする方法の簡単な分析

作者は最近、node でファイルの読み取り、書き込み、およびマルチパートのアップロード作業を行っています。このプロセス中に、ファイルが次によって読み取られた場合、ノードが 2G を超えると、2G を超えます。Blob の最大値を読み取るために、読み取り例外が発生します。また、ノード内のファイルの読み書きもサーバー RAM によって制限されます。読み込む必要があります。発生した問題とその解決方法を記録します。 [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル ]

  • ノードでのファイルの読み取りと書き込み
  • ノード ファイルの読み取りと書き込み RAM および BLOB サイズの制限
  • その他

1. ノードでのファイルの読み取りと書き込み

1.1 通常のファイルの読み取りと書き込み

通常、比較的小さなファイルを読み取りたい場合は、次のように直接渡すことができます:

const fs = require('fs')
let data = fs.readFileSync("./test.png")
console.log(data,123)
//输出data = <Buffer 89 50 4e ...>
ログイン後にコピー

一般的に、js/nodejs はシングルスレッドであるため、同期メソッドは推奨されません。メインスレッドをブロックします。最新バージョンのノードは fs.promise を直接提供しており、async/await と直接組み合わせて使用​​できます。

const fs = require('fs')
const readFileSync = async () => {
    let data = await fs.promises.readFile("./test.png")
    console.log(data,123)
}
readFileSync()
//输出data = <Buffer 89 50 4e ...>
ログイン後にコピー

ここでの非同期メソッド呼び出しはメインスレッドをブロックせず、複数のファイル読み取りの IO がブロックされる可能性があります。等も並行して行われます。

1.2 ストリーム ファイルの読み取りと書き込み

従来のファイルの読み取りと書き込みでは、ファイルを一度にメモリに読み取ります。この方法は時間とメモリの効率が高くなります。効率的です。両方とも非常に低いです。時間効率が低いということは、実行前にファイルを 1 回読み取る必要があることを意味します。メモリ効率が低いということは、ファイルを一度に読み取ってメモリに配置する必要があり、大量のメモリを消費することを意味します。したがって、この場合、通常は Stream を使用してファイルを読み取ります。

const fs = require('fs')
const readFileTest = () => {
    var data = ''
    var rs = fs.createReadStream('./test.png');
    rs.on('data', function(chunk) {
        data += chunk;
        console.log(chunk)
     });
    rs.on('end',function(){
        console.log(data);
    });
    rs.on('error', function(err){
        console.log(err.stack);
     });
}
readFileTest()
// data = <Buffer 89 50 64 ...>
ログイン後にコピー

Steam を介してファイルを読み書きすると、メモリ効率と時間効率が向上します。

  • メモリ効率: データを処理する前に大量 (またはデータ全体) をメモリにロードする必要はありません
  • 時間効率: データを取得したら、すぐに開始できますデータ全体がロードされるまで待つのではなく、データの処理を開始するのにかかる時間を大幅に短縮します。

ストリーム ファイルは 2 番目の書き込み方法もサポートしています:

const fs = require('fs')
const readFileTest = () => {
    var data = ''
    var chunk;
    var rs = fs.createReadStream('./test.png');
    rs.on('readable', function() {
    while ((chunk=rs.read()) != null) {
        data += chunk;
    }});
    rs.on('end', function() {
        console.log(data)
    });
};
readFileTest()
ログイン後にコピー

2. ノード ファイルの読み取りおよび書き込み RAM および Blob サイズの制限

2.1 基本的な質問

大きなファイルを読み取る場合、読み取りファイルのサイズに制限があります。たとえば、現在 2.5G ビデオ ファイルを読み取り中です:

const fs = require('fs')
const readFileTest = async () => {
    let data = await fs.promises.readFile("./video.mp4")
    console.log(data)
}
readFileTest()
ログイン後にコピー

上記のコードを実行するとエラーが報告されます:

RangeError [ERR_FS_FILE_TOO_LARGE]: ファイル サイズ (2246121911) は 2 GB を超えています

オプション NODE_OPTIONS='- を設定すると考えられるかもしれません。 -max -old-space-size=5000'、この時点では 5000M>2.5G ですが、エラーは依然として消えません。これは、ノードによって読み取られるファイルのサイズ制限をオプションで変更できないことを意味します。

上記は大容量ファイルを読み込む従来の方法ですが、Steam 経由で読み込む場合、ファイルサイズの制限はありますか?例:

const fs = require('fs')
const readFileTest = () => {
    var data = ''
    var rs = fs.createReadStream('./video.mp4');
    rs.on('data', function(chunk) {
        data += chunk;
     });
    rs.on('end',function(){
        console.log(data);
    });
    rs.on('error', function(err){
        console.log(err.stack);
     });
}
readFileTest()
ログイン後にコピー

上記の方法で 2.5G ファイルを読み取る場合は例外はありませんが、ここでエラーが発生することに注意してください:

data += chunk;
                ^

RangeError: Invalid string length
ログイン後にコピー

これは、データが最大制限 (2048M など) を超えています。そのため、Steamで処理する場合、読み込み結果を保存する際は、デフォルトのBufferの最大値を超えないようファイルサイズに注意してください。上記の場合、すべてのデータを 1 つの大きなデータに保存するための data = chunk は必要なく、読み込みと処理を同時に行うことができます。

2.2 分割読み取り

ファイルの読み取りプロセス中に、createReadStream は実際にセグメントを読み取ることができます。この分割読み取り方法も使用できます。大きなファイルの読み取り。特に同時読み取りの場合、特定の利点があり、ファイルの読み取りと処理の速度が向上します。

createReadStream は 2 番目のパラメータ {start, end} を受け入れます。 fs.promises.stat を通じてファイルのサイズを取得し、次にフラグメントを決定し、最後にフラグメントを 1 回読み取ることができます。例:

  1. ファイル サイズの取得
const info = await fs.promises.stat(filepath)
   const size = info.size
ログイン後にコピー
  1. 指定された SIZE に従ってフラグメント (フラグメントあたり 128M など)
  const SIZE = 128 * 1024 * 1024
  let sizeLen = Math.floor(size/SIZE)
    let total = sizeLen +1 ;
    for(let i=0;i<=sizeLen;i++){
      if(sizeLen ===i){
        console.log(i*SIZE,size,total,123)
        readStremfunc(i*SIZE,size,total)
      }else{
        console.log(i*SIZE,(i+1)*SIZE,total,456)
        readStremfunc(i*SIZE,(i+1)*SIZE-1,total)
      }
    }
  //分片后【0,128M】,【128M, 256M】...
ログイン後にコピー

3. 読み取り関数を実装します

const readStremfunc = () => {
    const readStream =  fs.createReadStream(filepath,{start:start,end:end})
    readStream.setEncoding('binary')
    let data = ''
    readStream.on('data', chunk => {
        data = data + chunk
    })
    readStream.end('data', () => {
      ...
    })
}
ログイン後にコピー

fs.createReadStream (filepath,{ start, end})、開始と終了は前後で閉じられます。たとえば、 fs.createReadSteam(filepath,{start:0,end:1023}) は [0,1023] を読み取り、合計 1024 ビットになります。

3. その他

3.1 ブラウザ側での大きなファイルの読み書きの拡張

大きなファイルは以前はnodejsに保存されていたので、ブラウザ側で大きなファイルを読み取ることに問題はありますか?

    浏览器在本地读取大文件时,之前有类似FileSaver、StreamSaver等方案,不过在浏览器本身添加了File的规范,使得浏览器本身就默认和优化了Stream的读取。我们不需要做额外的工作,相关的工作:github.com/whatwg/fs。不过不同的版本会有兼容性的问题,我们还是可以通过FileSaver等进行兼容。

3.2 请求静态资源大文件

    如果是在浏览器中获取静态资源大文件,一般情况下只需要通过range分配请求即可,一般的CDN加速域名,不管是阿里云还是腾讯云,对于分片请求都支持的很好,我们可以将资源通过cdn加速,然后在浏览器端直接请求cdn加速有的资源。

    分片获取cdn静态资源大文件的步骤为,首先通过head请求获取文件大小:

const getHeaderInfo = async (url: string) => {
  const res: any = await axios.head(url + `?${Math.random()}`);
  return res?.headers;
};
const header = getHeaderInfo(source_url)
const size = header['content-length']
ログイン後にコピー

我们可以从header中的content-length属性中,获取文件的大小。然后进行分片和分段,最后发起range请求:

const getRangeInfo = async (url: string, start: number, end: number) => {
    const data = await axios({
      method: 'get',
      url,
      headers: {
        range: `bytes=${start}-${end}`,
      },
      responseType: 'blob',
    });
    return data?.data;
  };
ログイン後にコピー

在headers中指定 range: bytes=${start}-${end},就可以发起分片请求去获取分段资源,这里的start和end也是前闭后闭的。

更多node相关知识,请访问:nodejs 教程

以上がNodejs が大きなファイルを読み書きする方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nodejs はバックエンド フレームワークですか? Nodejs はバックエンド フレームワークですか? Apr 21, 2024 am 05:09 AM

Node.js は、高いパフォーマンス、スケーラビリティ、クロスプラットフォーム サポート、豊富なエコシステム、開発の容易さなどの機能を備えているため、バックエンド フレームワークとして使用できます。

Nodejsをmysqlデータベースに接続する方法 Nodejsをmysqlデータベースに接続する方法 Apr 21, 2024 am 06:13 AM

MySQL データベースに接続するには、次の手順に従う必要があります。 mysql2 ドライバーをインストールします。 mysql2.createConnection() を使用して、ホスト アドレス、ポート、ユーザー名、パスワード、データベース名を含む接続オブジェクトを作成します。 connection.query() を使用してクエリを実行します。最後に connection.end() を使用して接続を終了します。

Nodejs インストール ディレクトリ内の npm ファイルと npm.cmd ファイルの違いは何ですか? Nodejs インストール ディレクトリ内の npm ファイルと npm.cmd ファイルの違いは何ですか? Apr 21, 2024 am 05:18 AM

Node.js インストール ディレクトリには、npm と npm.cmd という 2 つの npm 関連ファイルがあります。違いは次のとおりです。拡張子が異なります。npm は実行可能ファイルで、npm.cmd はコマンド ウィンドウのショートカットです。 Windows ユーザー: npm.cmd はコマンド プロンプトから使用できますが、npm はコマンド ラインからのみ実行できます。互換性: npm.cmd は Windows システムに固有ですが、npm はクロスプラットフォームで使用できます。使用上の推奨事項: Windows ユーザーは npm.cmd を使用し、他のオペレーティング システムは npm を使用します。

Nodejsのグローバル変数とは何ですか Nodejsのグローバル変数とは何ですか Apr 21, 2024 am 04:54 AM

Node.js には次のグローバル変数が存在します。 グローバル オブジェクト: グローバル コア モジュール: プロセス、コンソール、require ランタイム環境変数: __dirname、__filename、__line、__column 定数: unknown、null、NaN、Infinity、-Infinity

NodejsとJavaの間に大きな違いはありますか? NodejsとJavaの間に大きな違いはありますか? Apr 21, 2024 am 06:12 AM

Node.js と Java の主な違いは、設計と機能です。 イベント駆動型とスレッド駆動型: Node.js はイベント駆動型で、Java はスレッド駆動型です。シングルスレッドとマルチスレッド: Node.js はシングルスレッドのイベント ループを使用し、Java はマルチスレッド アーキテクチャを使用します。ランタイム環境: Node.js は V8 JavaScript エンジン上で実行され、Java は JVM 上で実行されます。構文: Node.js は JavaScript 構文を使用し、Java は Java 構文を使用します。目的: Node.js は I/O 集中型のタスクに適しており、Java は大規模なエンタープライズ アプリケーションに適しています。

PIノードティーチング:PIノードとは何ですか? PIノードをインストールしてセットアップする方法は? PIノードティーチング:PIノードとは何ですか? PIノードをインストールしてセットアップする方法は? Mar 05, 2025 pm 05:57 PM

ピン張りのノードの詳細な説明とインストールガイドこの記事では、ピネットワークのエコシステムを詳細に紹介します - PIノードは、ピン系生態系における重要な役割であり、設置と構成の完全な手順を提供します。 Pinetworkブロックチェーンテストネットワークの発売後、PIノードは多くの先駆者の重要な部分になり、テストに積極的に参加し、今後のメインネットワークリリースの準備をしています。まだピン張りのものがわからない場合は、ピコインとは何かを参照してください。リストの価格はいくらですか? PIの使用、マイニング、セキュリティ分析。パインワークとは何ですか?ピン競技プロジェクトは2019年に開始され、独占的な暗号通貨PIコインを所有しています。このプロジェクトは、誰もが参加できるものを作成することを目指しています

Nodejs はバックエンド開発言語ですか? Nodejs はバックエンド開発言語ですか? Apr 21, 2024 am 05:09 AM

はい、Node.js はバックエンド開発言語です。これは、サーバー側のビジネス ロジックの処理、データベース接続の管理、API の提供などのバックエンド開発に使用されます。

Nodejsプロジェクトをサーバーにデプロイする方法 Nodejsプロジェクトをサーバーにデプロイする方法 Apr 21, 2024 am 04:40 AM

Node.js プロジェクトのサーバー デプロイメント手順: デプロイメント環境を準備します。サーバー アクセスの取得、Node.js のインストール、Git リポジトリのセットアップ。アプリケーションをビルドする: npm run build を使用して、デプロイ可能なコードと依存関係を生成します。コードをサーバーにアップロードします: Git またはファイル転送プロトコル経由。依存関係をインストールする: サーバーに SSH で接続し、npm install を使用してアプリケーションの依存関係をインストールします。アプリケーションを開始します。node Index.js などのコマンドを使用してアプリケーションを開始するか、pm2 などのプロセス マネージャーを使用します。リバース プロキシの構成 (オプション): Nginx や Apache などのリバース プロキシを使用して、トラフィックをアプリケーションにルーティングします。

See all articles