Node.js でファイルを圧縮および解凍する方法

ファイルのアーカイブは、ファイルを圧縮してより小さく持ち運びしやすいフォーマットに変換することのメリットを誰もが実感できるため、現代世界では日常的に行われています。

ZIP フォーマットは、コンピューティングの世界で最もポピュラーなアーカイブ フォーマットの 1 つであり、ファイルをより良い保存、効率的な転送、その他の理由のためにアーカイブに変換する必要がある人にとって強く推奨される選択肢です。

それでは、ファイルを圧縮すべき理由と、Node.js を使用してファイルを ZIP に圧縮し、元の状態にプログラムで解凍する方法について考えてみましょう。

ファイルを圧縮する理由

ファイルやフォルダーが非常に大きくなり、共有や転送が問題になることがよくあります。それは、特定の容量のストレージ ドライブに保存するには大きすぎるか、クラウド ストレージにアップロードするのに時間がかかりすぎるためです。

このような場合やその他の多くの場合において、ファイルやフォルダーをはるかに小さいサイズに圧縮する必要があります。ファイルを圧縮すべきその他の理由として、より容易なファイル転送の他に次のようなものがあります。

  • 効率的な保存
  • より良いファイル構成と整理
  • セキュリティ (ファイルの暗号化とパスワード保護)
  • ファイルの完全性
  • ファイルのバージョン管理

Node.js の Archiver と Unzipper パッケージとは

Archiver パッケージの公式ドキュメントでは、パッケージを「アーカイブ生成のためのストリーミング インターフェイス」と説明しています。これは、Archiver パッケージが Node.js ストリームを活用して圧縮ファイル アーカイブを作成する関数のライブラリを提供することを意味します。

Archiver パッケージは、ZIP、GZIP、TAR を含む複数のアーカイブ フォーマットをデフォルトでサポートしています。このパッケージを使用すると、ファイルとディレクトリからアーカイブを作成したり、大きなアーカイブをより小さな部分 (複数ボリュームのアーカイブ) に分割したりすることもできます。圧縮中にファイルを除外またはフィルタリングすることもできます。

Unzipper パッケージは、Node.js で ZIP アーカイブを抽出するために非常に効率的なパッケージです。このパッケージは、開発者がわずか数行のコードで ZIP ファイルを抽出できる使いやすい API を提供します。

Archiver パッケージと Unzipper パッケージは、Node.js のfsモジュールとシームレスに統合され、スムーズな互換性とシンプルさを実現するため、このチュートリアルではこれらのパッケージが選択されています。

Node.js でファイルを ZIP フォーマットに圧縮する方法

Archiver パッケージのおかげで、Node.js でファイルを ZIP フォーマットに圧縮することは、他の言語と同様に簡単です。このセクションに従って Node.js で ZIP アーカイブを作成するには、コンピューターに Node.js 開発環境がセットアップされている必要があります。

次のコマンドを実行して、ファイルを ZIP フォーマットに圧縮する単純な Node.js スクリプトを作成します。

mkdir node-zip-archiver
cd node-zip-archiver
npm init -y

次に、プロジェクトに Archiver パッケージをインストールする必要があります。ターミナルでnpm install archiver --saveを実行してインストールします。パッケージのインストールが完了したら、プロジェクト ディレクトリに新しいファイルを作成し、app.jsarchiver.jsなど、任意の名前を付けます。

fsモジュールはファイル操作を処理し、Archiver パッケージはファイルとフォルダーの ZIP アーカイブへの圧縮を処理するため、スクリプトには両方のモジュールが必要です。

ファイルから ZIP アーカイブを作成

次のコードは、引数としてファイルを受け取り、そのファイルの圧縮された ZIP バージョンを作成する関数の実装です。

const archiver = require('archiver')
const fs = require('fs')

// create ZIP from file
const createZipFromFile = (file) => {
const filePath = __dirname + '/' + file
const output = fs.createWriteStream(filePath + '.zip')
const archive = archiver('zip', {
zlib: { level: 9 } // set compression level to the highest
})

archive.pipe(output);
archive.file(filePath, { name: file })
archive.finalize()
}

この関数は、圧縮するファイルのファイル名を取り、同様の名前の出力ファイル (唯一の違いは ZIP ファイル拡張子の追加) を生成します。

次に、圧縮レベルを 9 (最高) に設定した新しいアーカイブを生成し、pipe関数を使用してアーカイブの出力ストリームを出力ファイルの入力に転送します。

file関数は、アーカイブにファイルを追加します。パラメータとしてファイル パスと、アーカイブ内のファイルのプロパティを指定できるオプションのoptionsパラメータを受け入れます。

nameオプションは、アーカイブ内のファイルの名前を指定します。アーカイブにファイルを追加するときにオプションが指定されていない場合、Archiver は元のパスに基づいてアーカイブ内にファイルを設置し、ディレクトリ構造を維持します。

ただし、明示的に指定されると、Archiver はファイルを元のパスなしでアーカイブに追加し、アーカイブ内のカスタムの命名と整理が可能になります。

フォルダーから ZIP アーカイブを作成

フォルダーから ZIP アーカイブを作成するプロセスは、ファイルの場合とそれほど変わりません。主な違いは、Archiver パッケージのdirectory関数を、以前の関数のfileの代わりに使用することです。

フォルダーを ZIP アーカイブに圧縮する関数の実装を以下に示します。

// create ZIP from folder
const createZipFromFolder = (folder) => {
const folderPath = __dirname + '/' + folder
const output = fs.createWriteStream(folderPath + '.zip')

const archive = archiver('zip', {
zlib: { level: 9 } // set compression level to the highest
})

archive.pipe(output)
archive.directory(folderPath, false)
archive.finalize()
}

directory関数は、最初の引数としてフォルダーのパス、2 番目の引数としてフラグを受け取ります。フラグは、アーカイブ内のフォルダーの配置を決定します。

フラグがfalseに設定されている場合、生成されるアーカイブにはフォルダー自体を除くフォルダーの内容のみが含まれます。しかし、フラグがtrueに設定されている場合、Archiver は生成されたアーカイブにフォルダー自体を含めます。

圧縮されたアーカイブのファイルでアーカイブを抽出する場所を汚染しないようにしたい場合は、flagオプションをtrueに設定することを検討してください。ただし、目的に合っている場合はfalseに設定することもできます。

Node.js でファイルを解凍する方法

Node.js で ZIP ファイルを抽出するプロセスには複数の方法があり、使用可能なライブラリがいくつかありますが、この記事では Unzipper パッケージを使用します。

ターミナルで次のコマンドを実行して、プロジェクトに Unzipper パッケージをインストールします。

npm install unzipper --save

パッケージをインストールしたら、コードにインポートして、以下のコードに示す ZIP 抽出関数を実装します。

const unzipper = require("unzipper")

//function to extract ZIP file
const extractZip = async (file) => {
const filePath = __dirname + '/' + file
const outputPath = __dirname + '/extracted'
await fs.createReadStream(filePath)
.pipe(unzipper.Extract({ path: outputPath }))
.promise()
}

extractZip関数は、ZIP ファイルの内容を読み取るための読み取りストリームを作成し、ファイルを指定された出力パスに抽出する非同期関数です (存在しない場合はextractedフォルダーを作成します)。

解凍または抽出の場合、ZIP アーカイブは内容に関係なくファイルであるため、ファイルとフォルダーに対して異なる関数を定義する必要はありません。

以下は、これまで作成した関数をテストするためにアプリケーションに追加できる関数です。

(async function () {
const file = 'test.pdf'
const folder = 'test_folder'
const zipFile = 'test.pdf.zip'
createZipFromFile(file)
console.log('ZIP archive successfully created from file')
createZipFromFolder(folder)
console.log('ZIP archive successfully created from folder')
await extractZip(zipFile)
console.log('ZIP archive extracted successfully')
}) ()

以前の関数はすべて JavaScript のアロー関数ですが、上記の関数はImmediately Invoked Function Expressionであるため異なり、その中のコードをカプセル化してすぐに実行します。

ファイル圧縮は効率的なアプリケーションの構築に役立ちます

ユーザーに優れたサービスを提供し、快適なユーザー エクスペリエンスを維持するために、アプリケーションをできるだけ効率的にすることが常に目標であるべきです。

アプリケーション内で多くのファイルを転送する必要がある場合は、送信中にファイルを圧縮および解凍することを検討してください。ほとんどの最新のプログラミング言語は、ファイルを効率的に圧縮および解凍するためのサポートを提供しています。