ホームページ ウェブフロントエンド jsチュートリアル NestJS でのファイル アップロードの合理化: ディスク ストレージを使用しない CSV および XLSX の効率的なインメモリ解析

NestJS でのファイル アップロードの合理化: ディスク ストレージを使用しない CSV および XLSX の効率的なインメモリ解析

Oct 01, 2024 am 06:26 AM

NestJS 中的轻松文件解析:管理内存中的 CSV 和 XLSX 上传,以提高速度、安全性和可扩展性

介绍

在 Web 应用程序中处理文件上传是一项常见任务,但处理不同的文件类型并确保正确处理它们可能具有挑战性。通常,开发人员需要解析上传的文件而不将其保存到服务器,这对于降低服务器存储成本并确保敏感数据不会被不必要地保留尤为重要。在本文中,我们将逐步介绍创建自定义 NestJS 模块来处理专门针对 CSV 和 XLS/XLSX 文件的文件上传的过程,并且我们将使用 Node.js 流在内存中解析这些文件,因此不会有静态文件在服务器上创建。

为什么选择 NestJS?

NestJS 是一个渐进式 Node.js 框架,它利用 TypeScript 并提供开箱即用的应用程序架构,使您能够构建高度可测试、可扩展、松散耦合且易于维护的应用程序。通过使用 NestJS,我们可以利用其模块化结构、强大的依赖注入系统和广泛的生态系统。

第 1 步:设置项目

在深入研究代码之前,让我们先建立一个新的 NestJS 项目。如果您还没有安装 NestJS CLI:

npm install -g @nestjs/cli
ログイン後にコピー

创建一个新的 NestJS 项目:

nest new your-super-name
ログイン後にコピー

导航到项目目录:

cd your-super-name
ログイン後にコピー

第2步:安装所需的软件包

我们需要安装一些额外的软件包来处理文件上传和解析:

npm install @nestjs/platform-express multer exceljsfile-type
ログイン後にコピー
  • Multer:处理multipart/form-data的中间件,主要用于上传文件。
  • Exlesjs:用于解析 CSV/XLS/XLSX 文件的强大库。
  • File-Type:用于检测流或缓冲区的文件类型的库。

步骤 3:创建 Multer 存储引擎而不保存文件

为了自定义文件上传过程,我们将创建一个自定义 Multer 存储引擎。该引擎将确保仅接受 CSV 和 XLS/XLSX 文件,使用 Node.js 流在内存中解析它们,并返回解析后的数据,而不将任何文件保存到磁盘。

为我们的引擎创建一个新文件:

import { PassThrough } from 'stream';
import * as fileType from 'file-type';
import { BadRequestException } from '@nestjs/common';
import { Request } from 'express';
import { Workbook } from 'exceljs';
import { createParserCsvOrXlsx } from './parser-factory.js';

const ALLOWED_MIME_TYPES = [
  'text/csv',
  'application/vnd.ms-excel',
  'text/comma-separated-values',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'application/vnd.ms-excel',
] as const;

export class CsvOrXlsxMulterEngine {
  private destKey: string;
  private maxFileSize: number;
  constructor(opts: { destKey: string; maxFileSize: number }) {
    this.destKey = opts.destKey;
    this.maxFileSize = opts.maxFileSize;
  }
  async _handleFile(req: Request, file: any, cb: any) {
    try {
      const contentLength = Number(req.headers['content-length']);
      if (
        typeof contentLength === 'number' &&
        contentLength > this.maxFileSize
      ) {
        throw new Error(`Max file size is ${this.maxFileSize} bytes.`);
      }
      const fileStream = await fileType.fileTypeStream(file.stream);
      const mime = fileStream.fileType?.mime ?? file.mimetype;
      if (!ALLOWED_MIME_TYPES.includes(mime)) {
        throw new BadRequestException('File must be *.csv or *.xlsx');
      }
      const replacementStream = new PassThrough();
      fileStream.pipe(replacementStream);
      const parser = createParserCsvOrXlsx(mime);
      const data = await parser.read(replacementStream);
      cb(null, {
        [this.destKey]:
          mime === 'text/csv' ? data : (data as Workbook).getWorksheet(),
      });
    } catch (error) {
      cb(error);
    }
  }
  _removeFile(req: Request, file: any, cb: any) {
    cb(null);
  }
}
ログイン後にコピー

此自定义存储引擎检查文件的 MIME 类型并确保它是 CSV 或 XLS/XLSX 文件。然后,它使用 Node.js 流完全在内存中处理该文件,因此不会在服务器上创建临时文件。这种方法既高效又安全,尤其是在处理敏感数据时。

第 4 步:创建解析器工厂

解析器工厂负责根据文件类型确定合适的解析器。

为我们的解析器创建一个新文件:

import excel from 'exceljs';

export function createParserCsvOrXlsx(mime: string) {
  const workbook = new excel.Workbook();
  return [
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.ms-excel',
  ].includes(mime)
    ? workbook.xlsx
    : workbook.csv;
}
ログイン後にコピー

此工厂函数检查 MIME 类型并返回适当的解析器(xlsx 或 csv)。

第5步:在NestJS控制器中配置Multer

接下来,让我们创建一个控制器来使用我们的自定义存储引擎处理文件上传。

生成一个新的控制器:

nest g controller files
ログイン後にコピー

在files.controller.ts中,使用Multer和自定义存储引擎配置文件上传:

import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Worksheet } from 'exceljs';
import { CsvOrXlsxMulterEngine } from '../../shared/multer-engines/csv-xlsx/engine.js';
import { FilesService } from './files.service.js';

const MAX_FILE_SIZE_IN_MiB = 1000000000; // Only for test

@Controller('files')
export class FilesController {
  constructor(private readonly filesService: FilesService) {}
  @UseInterceptors(
    FileInterceptor('file', {
      storage: new CsvOrXlsxMulterEngine({
        maxFileSize: MAX_FILE_SIZE_IN_MiB,
        destKey: 'worksheet',
      }),
    }),
  )
  @Post()
  create(@UploadedFile() data: { worksheet: Worksheet }) {
    return this.filesService.format(data.worksheet);
  }
}
ログイン後にコピー

该控制器设置一个端点来处理文件上传。上传的文件由 CsvOrXlsxMulterEngine 处理,解析后的数据在响应中返回,而不会保存到磁盘。

第 6 步:设置模块

最后,我们需要设置一个模块来包含我们的控制器。

生成一个新模块:

nest g module files
ログイン後にコピー

在files.module.ts中,导入控制器:

import { Module } from '@nestjs/common';
import { FilesController } from './files.controller.js';
import { FilesService } from './files.service.js';

@Module({
  providers: [FilesService],
  controllers: [FilesController],
})
export class FilesModule {}
ログイン後にコピー

确保将此模块导入到您的 AppModule 中:

第 7 步:使用 HTML 测试文件上传

为了测试文件上传功能,我们可以创建一个简单的 HTML 页面,允许用户上传 CSV 或 XLS/XLSX 文件。此页面会将文件发送到我们的 /api/files 端点,该端点将在内存中进行解析和处理。

这是用于测试文件上传的基本 HTML 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload</title>
</head>
<body>
    <h1>Upload a File (CSV or XLSX)</h1>
    <form action="/api/files" method="post" enctype="multipart/form-data">
        <label for="file">Choose file:</label>
        <input type="file" id="file" name="file" accept=".csv, .xlsx" required>
        <br><br>
        <button type="submit">Upload</button>
    </form>
</body>
</html>
ログイン後にコピー

为了渲染文件上传的 HTML 页面,我们首先需要安装一个名为 @nestjs/serve-static 的附加 NestJS 模块。您可以通过运行以下命令来完成此操作:

npm install @nestjs/serve-static
ログイン後にコピー

安装后,我们需要在AppModule中配置该模块:

import { Module } from '@nestjs/common';
import { join } from 'path';
import { ServeStaticModule } from '@nestjs/serve-static';
import { FilesModule } from './modules/files/files.module.js';

@Module({
  imports: [
    FilesModule,
    ServeStaticModule.forRoot({
      rootPath: join(new URL('..', import.meta.url).pathname, 'public'),
      serveRoot: '/',
    }),
  ],
})
export class AppModule {}
ログイン後にコピー

此设置将允许我们从公共目录提供静态文件。现在,我们可以通过在浏览器中导航到http://localhost:3000来打开文件上传页面。

Streamline File Uploads in NestJS: Efficient In-Memory Parsing for CSV & XLSX Without Disk Storage

上传您的文件

To upload a file, follow these steps:

  1. Choose a file by clicking on the ‘Choose file’ button.
  2. Click on the ‘Upload’ button to start the upload process.

Once the file is uploaded successfully, you should see a confirmation that the file has been uploaded and formatted.

Streamline File Uploads in NestJS: Efficient In-Memory Parsing for CSV & XLSX Without Disk Storage

Note: I haven’t included code for formatting the uploaded file, as this depends on the library you choose for processing CSV or XLS/XLSX files. You can view the complete implementation on GitHub.
Comparing Pros and Cons of In-Memory File Processing
When deciding whether to use in-memory file processing or saving files to disk, it’s important to understand the trade-offs.

Pros of In-Memory Processing:

No Temporary Files on Disk:

  • Security: Sensitive data isn’t left on the server’s disk, reducing the risk of data leaks.
  • Resource Efficiency: The server doesn’t need to allocate disk space for temporary files, which can be particularly useful in environments with limited storage.

Faster Processing:

  • Performance: Parsing files in memory can be faster since it eliminates the overhead of writing and reading files from disk.
  • Reduced I/O Operations: Fewer disk I/O operations means lower latency and potent ially higher throughput for file processing.

Simplified Cleanup:

  • No Cleanup Required: Since files aren’t saved to disk, there’s no need to manage or clean up temporary files, simplifying the codebase.

Cons of In-Memory Processing:

Memory Usage:

  • High Memory Consumption: Large files can consume significant amounts of memory, which might lead to out-of-memory errors if the server doesn’t have enough resources.
  • Scalability: Handling large files or multiple file uploads simultaneously may require careful memory management and scaling strategies.

File Size Limitations:

  • Limited by Memory: The maximum file size that can be processed is limited by the available memory on the server. This can be a signific ant drawback for applications dealing with very large files.

Complexity in Error Handling:

  • Error Management: Managing errors in streaming data can be more complex than handling files on disk, especially in cases where partial data might need to be recovered or analyzed.

When to Use In-Memory Processing:

Small to Medium Files: If your application deals with relatively small files, in-memory processing can offer speed and simplicity.

Security-Sensitive Applications: When handling sensitive data that shouldn’t be stored on disk, in-memory processing can reduce the risk of data breaches.

High-Performance Scenarios: Applications that require high throughput and minimal latency may benefit from the reduced overhead of in-memory processing.

When to Consider Disk-Based Processing:

Large Files: If your application needs to process very large files, disk-based processing may be necessary to avoid running out of memory.

Resource-Constrained Environments: In cases where server memory is limited, processing files on disk can prevent memory exhaustion and allow for better resource management.

Persistent Storage Needs: If you need to retain a copy of the uploaded file for auditing, backup, or later retrieval, saving files to disk is necessary.

Integration with External Storage Services: For large files, consider uploading them to external storage services like AWS S3, Google Cloud

  • Storage, or Azure Blob Storage. These services allow you to offload storage from your server, and you can process the files in the cloud or retrieve them for in-memory processing as needed.

Scalability: Cloud storage solutions can handle massive files and provide redundancy, ensuring that your data is safe and easily accessible from multiple geographic locations.

Cost Efficiency: Using cloud storage can be more cost-effective for handling large files, as it reduces the need for local server resources and provides pay-as-you-go pricing.

結論

この記事では、CSV および XLS/XLSX ファイルを処理し、メモリ内で解析し、ディスクにファイルを保存せずに解析されたデータを返すカスタム ファイル アップロード モジュールを NestJS で作成しました。このアプローチでは Node.js ストリームの機能を活用し、サーバー上に一時ファイルが残らないため、効率的かつ安全になります。

また、メモリ内でのファイル処理とファイルをディスクに保存することの長所と短所についても検討しました。インメモリ処理は速度、セキュリティ、シンプルさを提供しますが、このアプローチを採用する前に、メモリ使用量と潜在的なファイル サイズ制限を考慮することが重要です。

エンタープライズ アプリケーションを構築している場合でも、小規模なプロジェクトを構築している場合でも、ファイルのアップロードを処理し、正しく解析することが重要です。この設定を使用すると、不要なサーバー ストレージやデータ セキュリティの問題を心配することなく、NestJS でのファイル アップロードをマスターできるようになります。

以下のコメントセクションでご意見や改善点をお気軽に共有してください!

この記事を楽しんでいただけた場合、またはこれらのツールが役に立ったと思われた場合は、コーディングと開発に関するさらなる洞察とヒントを得るために、Dev.to で私をフォローしてください。コーディング作業をスムーズにするために役立つコンテンツを定期的に共有します。

X (Twitter) で私をフォローしてください。そこでは、プログラミングとテクノロジーに関するさらに興味深い考え、最新情報、ディスカッションを共有します。お見逃しなく - フォローボタンをクリックしてください。

LinkedIn で私をフォローして、専門的な洞察、最新プロジェクトの最新情報、コーディングや技術トレンドなどについてのディスカッションを入手することもできます。開発スキルのレベルアップに役立つ貴重なコンテンツをお見逃しなく - つながりましょう!

以上がNestJS でのファイル アップロードの合理化: ディスク ストレージを使用しない CSV および XLSX の効率的なインメモリ解析の詳細内容です。詳細については、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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptとWeb:コア機能とユースケース JavaScriptとWeb:コア機能とユースケース Apr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScript in Action:実際の例とプロジェクト JavaScript in Action:実際の例とプロジェクト Apr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンの理解:実装の詳細 JavaScriptエンジンの理解:実装の詳細 Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:コミュニティ、ライブラリ、リソース Python vs. JavaScript:コミュニティ、ライブラリ、リソース Apr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Python vs. JavaScript:開発環境とツール Python vs. JavaScript:開発環境とツール Apr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

See all articles