JSZipでZipファイルを読み込む (javascript)

JavaScript

本家のReadMe見ただけでは使い方がわからなかったので、忘れないようにメモ書き。
今回はZipファイルを作成する目的ではなく、ローカルのZipファイルを読み込むのが目的です。

とある解析したいデータをwebからダウンロードした際にzip形式で渡ってくるため、いちいち手動で解凍するのが面倒というのが事の発端。自動的に解凍してからファイルを読み込んでもいいんですが、そもそも読み込む側でZipをそのまま読んでしまえばファイルも散らばらないし、管理もしやすいです。

JSZip
Create.zipfilesusingJavaScript.ProvidesasimpleAPItoplaceanycontentgeneratedbyJavaScriptintoa.zipfileforyourusers.
const fsPromises = require('fs').promises;
const JSZip = require('jszip');

const filePath = 'hoge.zip';
const buffer = await fsPromises.readFile(filePath);
const jsZip = await JSZip.loadAsync(buffer);
jsZip.forEach(async (relativePath, zipObject) => {
    console.log(relativePath);
    // => 'hoge.zip'
    
    console.log(zipObject);
    // {
    //     name: 'hoge.zip',
    //     dir: false,
    //     date: 2021-10-07T15:10:04.000Z,
    //     comment: null,
    //     unixPermissions: null,
    //     dosPermissions: 0,
    //     _data: {...},
    //     _dataBinary: true,
    //     options: { compression: null, compressionOptions: null }
    // }
    
    const content = await zipObject.async('nodebuffer');
    // content = fs.readFile(***);
});

JSZip.loadAsync() もしくは new JSZip().loadAsync()
でJSZipオブジェクトを初期化します。
この時にロードするファイルは適当にfs.readFile()で読み込んだcontentを与えてください。
ブラウザならfileInputから渡ってくるfileObjectとかになると思います。

JSZipオブジェクトはFileメソッドやFolderメソッドなどがあり、ここからファイル名やフォルダ名を指定することで該当のZipObjectを取得できます。
forEachメソッドも定義されているので、zip内のファイルをすべて処理する場合はこちらの方が楽だと思います。

そして私が悩んだのが、このZipObjectから解凍されたcontentをどうやって取得するの?という点でした。
結論から言うと、asyncメソッドを使って利用したいタイプに解凍します。
今回はnodejsなので
zipObject.async(‘nodebuffer’);
とnodebufferに変換しています。

Typeについては以下に公式の記載があるので、利用したいものに合わせて使い分けてください。

async(type[, onUpdate])
Create.zipfilesusingJavaScript.ProvidesasimpleAPItoplaceanycontentgeneratedbyJavaScriptintoa.zipfileforyourusers.

ということでここまで行けばfs.readFile()と変わりませんので、あとはどうとでもなります。

javascript界隈でzipを扱うといった検索をすると、どうもブラウザからzipファイルに固めてダウンロードする、という需要が大きいようです。以下のようなclient-zipもhttpリクエストを複数束ねて1つのzipとしてダウンロードしたり、という需要から作られている感じ。
ZIPファイルを解凍せずに読みたい、という感じの記事はあまりヒットしなかったので需要ないかもしれませんが、私にはニーズがあったということで。

GitHub - Touffy/client-zip: A client-side streaming ZIP generator
Aclient-sidestreamingZIPgenerator.ContributetoTouffy/client-zipdevelopmentbycreatinganaccountonGitHub.

コメント