Heim >Web-Frontend >js-Tutorial >Verwendung von Node.js zur Implementierung von Komprimierungs- und Dekomprimierungsfunktionen

Verwendung von Node.js zur Implementierung von Komprimierungs- und Dekomprimierungsfunktionen

亚连
亚连Original
2018-06-06 09:27:073879Durchsuche

In diesem Artikel wird hauptsächlich die auf Node.js basierende Komprimierungs- und Dekomprimierungsmethode vorgestellt. Jetzt teile ich sie mit Ihnen und gebe sie als Referenz.

Komprimierungsformate

zip und gzip sind die beiden häufigsten Komprimierungsformate, die wir sehen. Natürlich wird gzip selten unter Windows angezeigt.

tar ist ein Archivformat, das standardmäßig nicht komprimiert wird. Es muss mit gzip kombiniert werden, um die endgültige tar-Datei in eine tar.gz-Datei im gzip-Format zu komprimieren, das normalerweise mit tgz abgekürzt wird.

Warum wird rar nicht erwähnt? Da es sich um einen patentgeschützten Algorithmus handelt, können Sie das Dekomprimierungstool kostenlos erhalten, während das Komprimierungstool kostenpflichtig ist. Daher werden in unseren allgemeinen Anwendungsszenarien selten komprimierte RAR-Dateien bereitgestellt.

In diesem Artikel wird erläutert, wie die Komprimierung und Dekomprimierung von gzip, tar, tgz und zip unter Node.js implementiert wird.

Unkomprimierte Dateibibliothek

Die in diesem Artikel verwendete unkomprimierte Dateibibliothek stammt von urllib. Sie müssen sie zuerst klonen und in das angegebene Verzeichnis wechseln.

Git-Klon https://github.com/node-modules/urllib.git nodejs-compressing-demo

gzip

unter Linux In Die Verantwortlichkeiten jedes Tools sind sehr rein und sehr individuell. Beispielsweise komprimiert gzip nur Dateien und hat nichts damit zu tun .

gzip-Befehlszeile zum Komprimieren einer Datei

Wenn wir beispielsweise die Datei nodejs-compressing-demo/lib/urllib.js gzipen möchten, erhalten wir Wenn Sie eine urllib.js.gz-Datei erstellen, wird die Quelldatei gelöscht.

$ ls -l nodejs-compressing-demo/lib/urllib.js
-rw-r--r-- 1 a a 31318 Feb 12 11:27 nodejs-compressing-demo/lib/urllib.js

$ gzip nodejs-compressing-demo/lib/urllib.js

$ ls -l nodejs-compressing-demo/lib/urllib.js.gz
-rw-r--r-- 1 a a 8909 Feb 12 11:27 nodejs-compressing-demo/lib/urllib.js.gz

# 还原压缩文件
$ gunzip nodejs-compressing-demo/lib/urllib.js.gz

Dateigröße von 31318 Byte auf 8909 Byte reduziert, mehr als 3,5-fache Komprimierungswirkung.

Sie können auch die Pipe-Methode in Kombination mit dem Befehl cat verwenden, um die Datei zu komprimieren und als beliebige Datei zu speichern:

$ ls -l nodejs-compressing-demo/README.md
-rw-r--r-- 1 a a 13747 Feb 12 11:27 nodejs-compressing-demo/README.md

$ cat nodejs-compressing-demo/README.md | gzip > README.md.gz

$ ls -l README.md.gz
-rw-r--r-- 1 a a 4903 Feb 12 11:50 README.md.gz

Node.js implementiert gzip

Natürlich werden wir einen gzip-Algorithmus und ein gzip-Tool nicht wirklich von Grund auf implementieren. In der Welt von Node.js wurden diese grundlegenden Bibliotheken bereits für Sie vorbereitet, wir müssen sie nur sofort verwenden.

In diesem Artikel wird das Komprimierungsmodul verwendet, um alle Komprimierungs- und Dekomprimierungscodes zu implementieren.

Warum Komprimierung wählen? Weil es über ausreichende Codequalität und Unit-Testing-Garantien verfügt, sich in einem aktiven Wartungszustand befindet, über eine sehr benutzerfreundliche API verfügt und auch Streaming-Schnittstellen unterstützt.

Promise-Schnittstelle

const compressing = require('compressing');

// 选择 gzip 格式,然后调用 compressFile 方法
compressing.gzip.compressFile('nodejs-compressing-demo/lib/urllib.js', 'nodejs-compressing-demo/lib/urllib.js.gz')
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

// 解压缩是反响过程,接口都统一为 uncompress
compressing.gzip.uncompress('nodejs-compressing-demo/lib/urllib.js.gz', 'nodejs-compressing-demo/lib/urllib.js2')
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

In Kombination mit dem Async/Await-Programmiermodell kann der Code als normale asynchrone IO-Operation geschrieben werden.

const compressing = require('compressing');

async function main() {
 try {
  await compressing.gzip.compressFile('nodejs-compressing-demo/lib/urllib.js',
   'nodejs-compressing-demo/lib/urllib.js.gz');
  console.log('success');
 } catch (err) {
  console.error(err);
 }

 // 解压缩
 try {
  await compressing.gzip.uncompress('nodejs-compressing-demo/lib/urllib.js.gz',
   'nodejs-compressing-demo/lib/urllib.js2');
  console.log('success');
 } catch (err) {
  console.error(err);
 }
}

main();

Stream-Schnittstelle

Es ist wichtig zu beachten, dass Sie beim Programmieren im Stream-Modus das Fehlerereignis jedes Streams behandeln und alle Streams manuell zerstören müssen.

fs.createReadStream('nodejs-compressing-demo/lib/urllib.js')
 .on('error', handleError)
 .pipe(new compressing.gzip.FileStream()) // It's a transform stream
 .on('error', handleError)
 .pipe(fs.createWriteStream('nodejs-compressing-demo/lib/urllib.js.gz2'))
 .on('error', handleError);

// 解压缩,就是 pipe 的方向倒转过来
fs.createReadStream('nodejs-compressing-demo/lib/urllib.js.gz2')
 .on('error', handleError)
 .pipe(new compressing.gzip.UncompressStream()) // It's a transform stream
 .on('error', handleError)
 .pipe(fs.createWriteStream('nodejs-compressing-demo/lib/urllib.js3'))
 .on('error', handleError);

Gemäß der offiziellen Empfehlung für „Backpressuring in Streams“ sollten wir das Pumpenmodul verwenden, um mit der Stream-Modus-Programmierung zusammenzuarbeiten, und die Pumpe die Reinigungsarbeit dieser Streams abschließen lassen.

const pump = require('pump');

const source = fs.createReadStream('nodejs-compressing-demo/lib/urllib.js');
const target = fs.createWriteStream('nodejs-compressing-demo/lib/urllib.js.gz2');

pump(source, new compressing.gzip.FileStream(), target, err => {
 if (err) {
  console.error(err);
 } else {
  console.log('success');
 }
});

// 解压缩
pump(fs.createReadStream('nodejs-compressing-demo/lib/urllib.js.gz2'),
  new compressing.gzip.FileStream(),
  fs.createWriteStream('nodejs-compressing-demo/lib/urllib.js3'),
  err => {
 if (err) {
  console.error(err);
 } else {
  console.log('success');
 }
});

Vorteile der Stream-Schnittstelle

Die Stream-Schnittstelle scheint viel komplizierter zu sein als die Promise-Schnittstelle. Warum gibt es ein solches Anwendungsszenario?

Tatsächlich bietet das Stream-Modell im Bereich der HTTP-Dienste größere Vorteile, da die HTTP-Anfrage selbst ein Request Stream ist. Wenn Sie eine hochgeladene Datei mit GZIP-Komprimierung zurückgeben möchten, ist dies nicht erforderlich um die hochgeladene Datei über die Stream-Schnittstelle auf der lokalen Festplatte zu speichern, diesen Dateistream jedoch direkt zu konsumieren.

Mit dem Beispielcode für das Hochladen von Eierdateien können wir die GZIP-Komprimierung implementieren und mit einer geringfügigen Änderung zurückgeben.

const pump = require('pump');

class UploadFormController extends Controller {
 // ... other codes

 async upload() {
  const stream = await this.ctx.getFileStream();
  // 直接将压缩流赋值给 ctx.body,实现边压缩边返回的流式响应
  this.ctx.body = pump(stream, new compressing.gzip.FileStream());
 }
}

tar |.gzip > tgz

gzip Kapitel Sie können im Voraus wissen, dass tar für die Verpackung des Ordners verantwortlich ist:Paket:.

Wenn Sie beispielsweise den gesamten Ordner nodejs-compressing-dem o in eine Datei packen und an andere senden möchten, können Sie den Befehl tar verwenden.

$ tar -c -f nodejs-compressing-demo.tar nodejs-compressing-demo/

$ ls -l nodejs-compressing-demo.tar
-rw-r--r-- 1 a a 206336 Feb 12 14:01 nodejs-compressing-demo.tar

Wie Sie sehen können, ist die von tar gepackte Datei im Allgemeinen größer, da sie unkomprimiert ist und die Größe nahe an der tatsächlichen Gesamtgröße des Ordners liegt. Wir komprimieren also alle gleichzeitig mit dem Verpacken.

$ tar -c -z -f nodejs-compressing-demo.tgz nodejs-compressing-demo/

$ ls -l nodejs-compressing-demo.tgz
-rw-r--r-- 1 a a 39808 Feb 12 14:07 nodejs-compressing-demo.tgz

Der Größenunterschied zwischen tar und tgz beträgt mehr als das Fünffache, was die Netzwerkübertragungsbandbreite erheblich reduzieren kann.

Node.js implementiert tgz

Promise-Schnittstelle

Verwenden Sie zunächst compressing.tar.compressDir(sourceDir, targetFile) für Packen Sie einen Ordner in eine TAR-Datei und komprimieren Sie die TAR-Datei dann mit der oben genannten gzip-Komprimierungsmethode in eine TGZ-Datei.

const compressing = require('compressing');

compressing.tar.compressDir('nodejs-compressing-demo', 'nodejs-compressing-demo.tar')
 .then(() => {
  return compressing.gzip.compressFile('nodejs-compressing-demo.tar',
   'nodejs-compressing-demo.tgz');
 });
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

// 解压缩
compressing.gzip.uncompress('nodejs-compressing-demo.tgz', 'nodejs-compressing-demo.tar')
 .then(() => {
  return compressing.tar.uncompress('nodejs-compressing-demo.tar',
   'nodejs-compressing-demo2');
 });
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

In Kombination mit dem Async/Wait-Programmiermodell wird der Code einfacher zu lesen:

const compressing = require('compressing');

async function main() {
 try {
  await compressing.tar.compressDir('nodejs-compressing-demo',
   'nodejs-compressing-demo.tar');
  await compressing.gzip.compressFile('nodejs-compressing-demo.tar',
   'nodejs-compressing-demo.tgz');
  console.log('success');
 } catch (err) {
  console.error(err);
 }
 
 // 解压缩
 try {
  await compressing.gzip.uncompress('nodejs-compressing-demo.tgz',
   'nodejs-compressing-demo.tar');
  await compressing.tar.uncompress('nodejs-compressing-demo.tar',
   'nodejs-compressing-demo2');
  console.log('success');
 } catch (err) {
  console.error(err);
 }
}

main();

Stream-Schnittstelle

über compressing.tar. Mit der Stream-Klasse können Sie beliebige Dateien und Ordner dynamisch zu einem TAR-Stream-Objekt hinzufügen, was sehr flexibel ist.

const tarStream = new compressing.tar.Stream();
// dir
tarStream.addEntry('dir/path/to/compress');
// file
tarStream.addEntry('file/path/to/compress');
// buffer
tarStream.addEntry(buffer);
// stream
tarStream.addEntry(stream);

const destStream = fs.createWriteStream('path/to/destination.tgz');
pump(tarStream, new compressing.gzip.FileStream(), destStream, err => {
 if (err) {
  console.error(err);
 } else {
  console.log('success');
 }
});

zip

zip kann eigentlich als „kommerzielle“ Kombination aus tar + gzip angesehen werden. Es ermöglicht Benutzern, nicht zwischen komprimierten Dateien und komprimierten Ordnern zu unterscheiden. Wie auch immer, benutze einfach meine Zip-Datei.

Beispiel für die Verwendung des Zip-Befehlszeilentools zum Komprimieren eines Ordners:

$ zip -r nodejs-compressing-demo.zip nodejs-compressing-demo/
 adding: nodejs-compressing-demo/ (stored 0%)
 adding: nodejs-compressing-demo/test/ (stored 0%)
 ...
 adding: nodejs-compressing-demo/.travis.yml (deflated 36%)

$ ls -l nodejs-compressing-demo.*
-rw-r--r-- 1 a a 206336 Feb 12 14:06 nodejs-compressing-demo.tar
-rw-r--r-- 1 a a  39808 Feb 12 14:07 nodejs-compressing-demo.tgz
-rw-r--r-- 1 a a  55484 Feb 12 14:34 nodejs-compressing-demo.zip

Durch den Vergleich der Dateigrößen von tgz und zip ist ersichtlich, dass gzip unter den Standardkomprimierungsparametern eine hat bessere Wirkung als Zip.

Node.js implementiert zip

Der Implementierungscode ähnelt tar, außer dass er standardmäßig komprimiert ist und es nicht erforderlich ist, den gzip-Prozess hinzuzufügen.

const compressing = require('compressing');

compressing.zip.compressDir('nodejs-compressing-demo', 'nodejs-compressing-demo.zip')
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

// 解压缩
compressing.zip.uncompress('nodejs-compressing-demo.zip', 'nodejs-compressing-demo3')
 .then(() => {
  console.log('success');
 })
 .catch(err => {
  console.error(err);
 });

Zusammenfassung

Ist die Komprimierung und Dekomprimierung auf Basis von Node.js einfacher als gedacht? Dank des riesigen NPM können wir die einfache Erfahrung des Programmierens mit Befehlszeilentools machen.

Ob es sich um die Promise-Schnittstelle oder die Stream-Schnittstelle handelt, es gibt das am besten geeignete Szenario. Werden Sie es wählen?

Welche Art von Diensten und Funktionen können Sie zum jetzigen Zeitpunkt mit den Ihnen zur Verfügung stehenden Komprimierungs- und Dekomprimierungsfunktionen ausführen?

Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.

Verwandte Artikel:

Verwenden von tween.js zum Implementieren des Easing-Tween-Animationsalgorithmus

Erläutern Sie Refs in React im Detail (ausführliches Tutorial)

So erzielen Sie mit JS einen intermittierenden Text-Scroll-Effekt

Das obige ist der detaillierte Inhalt vonVerwendung von Node.js zur Implementierung von Komprimierungs- und Dekomprimierungsfunktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn