Heim >Web-Frontend >js-Tutorial >Optimieren Sie Datei-Uploads in NestJS: Effizientes In-Memory-Parsing für CSV und XLSX ohne Festplattenspeicher
Mühelose Dateianalyse in NestJS: Verwalten Sie CSV- und XLSX-Uploads im Speicher für Geschwindigkeit, Sicherheit und Skalierbarkeit
Das Hochladen von Dateien in einer Webanwendung ist eine häufige Aufgabe, aber der Umgang mit verschiedenen Dateitypen und die Sicherstellung, dass sie korrekt verarbeitet werden, kann eine Herausforderung sein. Häufig müssen Entwickler hochgeladene Dateien analysieren, ohne sie auf dem Server zu speichern. Dies ist besonders wichtig, um die Serverspeicherkosten zu senken und sicherzustellen, dass vertrauliche Daten nicht unnötig aufbewahrt werden. In diesem Artikel gehen wir durch den Prozess der Erstellung eines benutzerdefinierten NestJS-Moduls, um Datei-Uploads speziell für CSV- und XLS/XLSX-Dateien zu verarbeiten, und wir analysieren diese Dateien im Speicher mithilfe von Node.js-Streams, sodass keine statischen Dateien vorhanden sind auf dem Server erstellt.
NestJS ist ein progressives Node.js-Framework, das TypeScript nutzt und eine sofort einsatzbereite Anwendungsarchitektur bietet, die es Ihnen ermöglicht, hochgradig testbare, skalierbare, lose gekoppelte und leicht zu wartende Anwendungen zu erstellen. Durch die Verwendung von NestJS können wir von seiner modularen Struktur, seinem leistungsstarken Abhängigkeitsinjektionssystem und seinem umfangreichen Ökosystem profitieren.
Bevor wir uns mit dem Code befassen, richten wir ein neues NestJS-Projekt ein. Falls noch nicht geschehen, installieren Sie die NestJS-CLI:
npm install -g @nestjs/cli
Erstellen Sie ein neues NestJS-Projekt:
nest new your-super-name
Navigieren Sie in das Projektverzeichnis:
cd your-super-name
Wir müssen einige zusätzliche Pakete installieren, um das Hochladen und Parsen von Dateien zu ermöglichen:
npm install @nestjs/platform-express multer exceljsfile-type
Um den Datei-Upload-Prozess anzupassen, erstellen wir eine benutzerdefinierte Multer-Speicher-Engine. Diese Engine stellt sicher, dass nur CSV- und XLS/XLSX-Dateien akzeptiert werden, analysiert sie im Speicher mithilfe von Node.js-Streams und gibt die analysierten Daten zurück, ohne Dateien auf der Festplatte zu speichern.
Erstellen Sie eine neue Datei für unsere Engine:
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); } }
Diese benutzerdefinierte Speicher-Engine überprüft den MIME-Typ der Datei und stellt sicher, dass es sich entweder um eine CSV- oder XLS/XLSX-Datei handelt. Anschließend wird die Datei mithilfe von Node.js-Streams vollständig im Speicher verarbeitet, sodass keine temporären Dateien auf dem Server erstellt werden. Dieser Ansatz ist sowohl effizient als auch sicher, insbesondere im Umgang mit sensiblen Daten.
Die Parser-Factory ist dafür verantwortlich, den geeigneten Parser basierend auf dem Dateityp zu bestimmen.
Erstellen Sie eine neue Datei für unseren Parser:
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; }
Diese Factory-Funktion prüft den MIME-Typ und gibt den entsprechenden Parser zurück (entweder xlsx oder csv).
Als nächstes erstellen wir einen Controller, um Datei-Uploads mithilfe unserer benutzerdefinierten Speicher-Engine zu verarbeiten.
Neuen Controller erstellen:
nest g controller files
Konfigurieren Sie in files.controller.ts den Datei-Upload mit Multer und der benutzerdefinierten Speicher-Engine:
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); } }
Dieser Controller richtet einen Endpunkt für die Verarbeitung von Datei-Uploads ein. Die hochgeladene Datei wird von der CsvOrXlsxMulterEngine verarbeitet und die analysierten Daten werden in der Antwort zurückgegeben, ohne jemals auf der Festplatte gespeichert zu werden.
Zuletzt müssen wir ein Modul einrichten, um unseren Controller einzubinden.
Neues Modul generieren:
nest g module files
Im files.module.ts importieren Sie den Controller:
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 {}
Stellen Sie sicher, dass Sie dieses Modul in Ihr AppModule importieren:
Um die Funktion zum Hochladen von Dateien zu testen, können wir eine einfache HTML-Seite erstellen, die es Benutzern ermöglicht, CSV- oder XLS/XLSX-Dateien hochzuladen. Diese Seite sendet die Datei an unseren /api/files-Endpunkt, wo sie analysiert und im Speicher verarbeitet wird.
Hier ist die grundlegende HTML-Datei zum Testen des Datei-Uploads:
<!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>
Um die HTML-Seite für Datei-Uploads zu rendern, müssen wir zunächst ein zusätzliches NestJS-Modul namens @nestjs/serve-static installieren. Sie können dies tun, indem Sie den folgenden Befehl ausführen:
npm install @nestjs/serve-static
Nach der Installation müssen wir dieses Modul in AppModule konfigurieren:
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 {}
Dieses Setup ermöglicht es uns, statische Dateien aus dem öffentlichen Verzeichnis bereitzustellen. Jetzt können wir die Datei-Upload-Seite öffnen, indem wir in Ihrem Browser zu http://localhost:3000 navigieren.
Laden Sie Ihre Datei hoch
Um eine Datei hochzuladen, befolgen Sie diese Schritte:
Sobald die Datei erfolgreich hochgeladen wurde, sollten Sie eine Bestätigung sehen, dass die Datei hochgeladen und formatiert wurde.
Hinweis: Ich habe keinen Code zum Formatieren der hochgeladenen Datei eingefügt, da dies von der Bibliothek abhängt, die Sie für die Verarbeitung von CSV- oder XLS/XLSX-Dateien auswählen. Sie können die vollständige Implementierung auf GitHub ansehen.
Vergleich der Vor- und Nachteile der In-Memory-Dateiverarbeitung
Bei der Entscheidung, ob Sie die In-Memory-Dateiverarbeitung verwenden oder Dateien auf der Festplatte speichern möchten, ist es wichtig, die Kompromisse zu verstehen.
Keine temporären Dateien auf der Festplatte:
Schnellere Verarbeitung:
Vereinfachte Bereinigung:
Speichernutzung:
Dateigrößenbeschränkungen:
Komplexität in der Fehlerbehandlung:
Kleine bis mittlere Dateien: Wenn Ihre Anwendung relativ kleine Dateien verarbeitet, kann die In-Memory-Verarbeitung Geschwindigkeit und Einfachheit bieten.
Sicherheitssensible Anwendungen: Beim Umgang mit sensiblen Daten, die nicht auf der Festplatte gespeichert werden sollten, kann die In-Memory-Verarbeitung das Risiko von Datenschutzverletzungen verringern.
Hochleistungsszenarien: Anwendungen, die einen hohen Durchsatz und minimale Latenz erfordern, können vom geringeren Overhead der In-Memory-Verarbeitung profitieren.
Große Dateien: Wenn Ihre Anwendung sehr große Dateien verarbeiten muss, ist möglicherweise eine festplattenbasierte Verarbeitung erforderlich, um zu vermeiden, dass Ihnen der Speicher ausgeht.
Umgebungen mit eingeschränkten Ressourcen: In Fällen, in denen der Serverspeicher begrenzt ist, kann die Verarbeitung von Dateien auf der Festplatte eine Speichererschöpfung verhindern und eine bessere Ressourcenverwaltung ermöglichen.
Persistenter Speicherbedarf: Wenn Sie eine Kopie der hochgeladenen Datei zur Prüfung, Sicherung oder zum späteren Abruf aufbewahren müssen, ist das Speichern der Dateien auf der Festplatte erforderlich.
Integration mit externen Speicherdiensten: Erwägen Sie bei großen Dateien das Hochladen auf externe Speicherdienste wie AWS S3, Google Cloud
Skalierbarkeit: Cloud-Speicherlösungen können große Dateien verarbeiten und Redundanz bieten, sodass Ihre Daten sicher und von mehreren geografischen Standorten aus leicht zugänglich sind.
Kosteneffizienz: Die Verwendung von Cloud-Speicher kann für die Verarbeitung großer Dateien kostengünstiger sein, da dadurch der Bedarf an lokalen Serverressourcen reduziert wird und eine nutzungsbasierte Preisgestaltung möglich ist.
In diesem Artikel haben wir ein benutzerdefiniertes Datei-Upload-Modul in NestJS erstellt, das CSV- und XLS/XLSX-Dateien verarbeitet, sie im Speicher analysiert und die analysierten Daten zurückgibt, ohne Dateien auf der Festplatte zu speichern. Dieser Ansatz nutzt die Leistungsfähigkeit der Node.js-Streams und macht ihn sowohl effizient als auch sicher, da keine temporären Dateien auf dem Server verbleiben.
Wir haben auch die Vor- und Nachteile der In-Memory-Dateiverarbeitung im Vergleich zum Speichern von Dateien auf der Festplatte untersucht. Während die In-Memory-Verarbeitung Geschwindigkeit, Sicherheit und Einfachheit bietet, ist es wichtig, die Speichernutzung und mögliche Einschränkungen der Dateigröße zu berücksichtigen, bevor Sie diesen Ansatz übernehmen.
Unabhängig davon, ob Sie eine Unternehmensanwendung oder ein kleines Projekt erstellen, ist der korrekte Umgang mit dem Hochladen und Parsen von Dateien von entscheidender Bedeutung. Mit diesem Setup sind Sie auf dem besten Weg, Datei-Uploads in NestJS zu meistern, ohne sich Gedanken über unnötigen Serverspeicher oder Datensicherheitsprobleme machen zu müssen.
Zögern Sie nicht, Ihre Gedanken und Verbesserungen im Kommentarbereich unten mitzuteilen!
Wenn Ihnen dieser Artikel gefallen hat oder Sie diese Tools nützlich fanden, folgen Sie mir unbedingt auf Dev.to, um weitere Einblicke und Tipps zu Codierung und Entwicklung zu erhalten. Ich teile regelmäßig hilfreiche Inhalte, um Ihre Programmierreise reibungsloser zu gestalten.
Folgen Sie mir auf X (Twitter), wo ich weitere interessante Gedanken, Updates und Diskussionen über Programmierung und Technologie teile! Verpassen Sie es nicht - klicken Sie auf die Schaltflächen „Folgen“.
Sie können mir auch auf LinkedIn folgen, um berufliche Einblicke, Updates zu meinen neuesten Projekten und Diskussionen über Codierung, Technologietrends und mehr zu erhalten. Verpassen Sie nicht wertvolle Inhalte, die Ihnen helfen können, Ihre Entwicklungsfähigkeiten zu verbessern – Lass uns vernetzen!
Das obige ist der detaillierte Inhalt vonOptimieren Sie Datei-Uploads in NestJS: Effizientes In-Memory-Parsing für CSV und XLSX ohne Festplattenspeicher. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!