zlibjsのUnzipを使用してブラウザ上でzipファイルを展開する

ブラウザで複数ファイルをxhrで取得したいときや、数メガのファイルを取得したいとき、これらを纏めて１リクエストで済ませたい場合があります。

[zlib.jsのUnzip](https://github.com/imaya/zlib.js#pkzip-1)を使用すると、xhrで取得したzipをその場で展開し、直ぐに中のファイルを使用することが出来ます。

# ファイル名一覧の取得

```bash:zlib-example
tree files
# files
# ├── bar.png
# └── foo.json

zip -r files files
# adding...
```

上記のような確認用の [zipファイル](http://jsrun.it/assets/u/s/4/i/us4ia) を作成します。

```json:package.json
{
  "name": "zlibjs-test",
  "dependencies": {
    "zlibjs": "^0.2.0"
  },

  "scripts": {
    "start": "beefy index.js --open"
  },
  "devDependencies": {
    "beefy": "^2.1.5"
  }
}
```

上記`package.json`を使用して、browserify環境を作成します。

```js:index.js
var Unzip= require('zlibjs/bin/unzip.min').Zlib.Unzip

var url= 'files.zip'
var xhr= new XMLHttpRequest
xhr.open('GET',url,true)
xhr.responseType= 'arraybuffer'
xhr.send()

xhr.addEventListener('load',function(){
  var unzip= new Unzip(new Buffer(xhr.response))
  var filenames= unzip.getFilenames()
  
  console.log(filenames)
})
```

`unzip.getFilenames`メソッドから、読み込んだzipファイル名の一覧を取得できます。

上記３ファイルを用意すれば、下記のように動作を確認できます。

```bash
tree .
# .
# ├── files.zip
# ├── index.js
# └── package.json

npm install
# ...
npm start
# beefy (v2.1.5) is listening on http://127.0.0.1:9966
```
![スクリーンショット 2015-12-21 10.04.30.png](https://qiita-image-store.s3.amazonaws.com/0/28576/ef524b54-e83f-807c-e3dc-4943e08f995b.png)

# 解凍

`unzip.decompress`メソッドに、解凍したいファイル名を指定すると、指定したファイルの`Uint8Array`を返します。

JSONであれば、下記のようにパースできます。

```js
var Unzip= require('zlibjs/bin/unzip.min').Zlib.Unzip

var url= 'files.zip'
var xhr= new XMLHttpRequest
xhr.open('GET',url,true)
xhr.responseType= 'arraybuffer'
xhr.send()

xhr.addEventListener('load',function(){
  var unzip= new Unzip(new Buffer(xhr.response))
  var filenames= unzip.getFilenames()

  var filename= filenames[2]// foo.json
  var buffer= new Buffer(unzip.decompress(filename))
  var object= JSON.parse(buffer.toString())

  console.log(object)
  // {foo: "i am json"}
})
```


画像であれば、下記のように`datauri`に変換可能です。

```js
var Unzip= require('zlibjs/bin/unzip.min').Zlib.Unzip

var url= 'files.zip'
var xhr= new XMLHttpRequest
xhr.open('GET',url,true)
xhr.responseType= 'arraybuffer'
xhr.send()

xhr.addEventListener('load',function(){
  var unzip= new Unzip(new Buffer(xhr.response))
  var filenames= unzip.getFilenames()

  var filename= filenames[1]// bar.png
  var buffer= new Buffer(unzip.decompress(filename))
  var dataURI= 'data:image/png;base64,'+buffer.toString('base64')
  
  console.log(dataURI)
  // data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia219thzg25abkRE/BpDc3pqvphHvRFys2weqvp+krbWKIX7nhDbzLOItiM8358pTwdirqpPFnMF2xLc1WvLyOwTAibpbmvHHcvttU57y5+XqNZrLe3lE/Pq8eUj2fXKfOe3pfOjzhJYtB/yll5SDFcSDiH+hRkH25+L+sdxKEAMZahrlSX8ukqMOWy/jXW2m6M9LDBc31B9LFuv6gVKg/0Szi3KAr1kGq1GMjU/aLbnq6/lRxc4XfJ98hTargX++DbMJBSiYMIe9Ck1YAxFkKEAG3xbYaKmDDgYyFK0UGYpfoWYXG+fAPPI6tJnNwb7ClP7IyF+D+bjOtCpkhz6CFrIa/I6sFtNl8auFXGMTP34sNwI/JhkgEtmDz14ySfaRcTIBInmKPE32kxyyE2Tv+thKbEVePDfW/byMM1Kmm0XdObS7oGD/MypMXFPXrCwOtoYjyyn7BV29/MZfsVzpLDdRtuIZnbpXzvlf+ev8MvYr/Gqk4H/kV/G3csdazLuyTMPsbFhzd1UabQbjFvDRmcWJxR3zcfHkVw9GfpbJmeev9F08WW8uDkaslwX6avlWGU6NRKz0g/SHtCy9J30o/ca9zX3Kfc19zn3BXQKRO8ud477hLnAfc1/G9mrzGlrfexZ5GLdn6ZZrrEohI2wVHhZywjbhUWEy8icMCGNCUdiBlq3r+xafL549HQ5jH+an+1y+LlYBifuxAvRN/lVVVOlwlCkdVm9NOL5BE4wkQ2SMlDZU97hX86EilU/lUmkQUztTE6mx1EEPh7OmdqBtAvv8HdWpbrJS6tJj3n0CWdM6busNzRV3S9KTYhqvNiqWmuroiKgYhshMjmhTh9ptWhsF7970j/SbMrsPE1suR5z7DMC+P/Hs+y7ijrQAlhyAgccjbhjPygfeBTjzhNqy28EdkUh8C+DU9+z2v/oyeH791OncxHOs5y2AtTc7nb/f73TWPkD/qwBnjX8BoJ98VVBg/m8AAAAdSURBVBgZY2RgYPgPxAQBE0EVUAWjCvGGFNHBAwCmFwEThd/6KQAAAABJRU5ErkJggg==
})
```

# さいごに／成果物
[ハースストーンの5MB超の翻訳データがjsonで配布されており](https://hearthstonejson.com/)、これをgit管理せず利用する方法を考えたところ、当ライブラリに行き着きました。

実際に[React](http://qiita.com/tags/React)や[Lodash](http://qiita.com/tags/lodash)と併用して、コレクション可能なカードをフリーワードで検索できるツールを作成してみました。

[ハースストーンカード日本語検索 - jsdo.it](http://jsdo.it/59naga/hscdje)