Archive API proposalに触ってみた

772434 – Blob support for Zip file contents
が、一週間ちょいほど前にMozilla-centralに投入された。何事もなければ、Firefox 17で使えるようになると思う。

これはどういうものなのかというと、zipなアーカイブファイルを取り扱うために、FileReaderのような新しいコンストラクタArchiveReaderを追加するもの。

話の出所はおそらくこれ [whatwg] Archive API - proposal だと思う(whatwgとかまではさすがに追えてないです……)。このメールアーカイブ自体も7/17のものなので、完全に試験実装として載せた感じ。導入の目的はゲーム用途と書かれている。

現在のところ、実装されたAPIのidlはこれ。

Firefoxのテストコードはこんな感じ。

FileReaderと似てるけど異なる点として、FileReaderインスタンスイベントハンドラ(コールバック)を設定して、読み出したデータに触るのに対して、ArchiveReaderでは、ArchiveReader.getFilenames()およびArchiveReader.getFile()の返り値であるArchiveRequestイベントハンドラを設定する点。なんかややこしいですね。

前置きはこんなところとして、ものは試しにサンプルを作ってみた。

Archive API sample for Firefox Nightly 17 — Gist

テキストファイルのエンコード判別未実装とか、色々と雑なんだけど、とりあえずこんなことができましたみたいな感じで。実装の安全性とかはほとんど考えていないので、実行の際には注意してください。ちなみにパスワードをかけたzipファイルを渡すと、file.typeapplication/x-javascrpitだったりした。

また、渡したzip内のファイルが大きすぎると、ファイルの読み出しが中途半端な状態のまま処理が進行してしまうバグがあるみたい(たとえば画像だったり動画だったり)。ArchiveRequestがどの段階でsuccessイベントを発行しているのかは実装コードを精読していないのでわからないけれども、ある程度の読み出しが終わったら発行しているようで、Blobからwindow.createObjectURL()するとファイルの展開が中途半端なまま終わるし、ArchiveReader.getFile()Fileを取得してFileReader.readAsDataURL()でもdataURIが中途半端な値である旨の警告が表示されるものの、完全に展開されること無く処理が進む。(ArchiveRequest.onloadとか設定すれば行けるかと思ったけれども、loadイベントが発行されないのでダメ)。

この辺りは試験実装だし仕方ないね。

XHRなどでリソース一式をzipで固めたものを遅延読み込みさせて、クライアント側で展開することで、コネクションとか転送量とか減らせそうだなと思った。メモリもその分食うだろうけど、使える頃にはモバイル含めて搭載メモリ量が太っ腹になってるのを期待しましょう。

Mozilla developer street にも似たような内容をクロスポストしました。
Archive API experimental implement rev.2012.07.28. | Mozilla Developer Street (modest)