end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

javascriptで、sjisな日本語ファイル名を含むzipを解凍(unzip)し、一覧表示

以前も同様のエントリを記載していますが、 その際、参考にさせて頂いた hinata.in が閉鎖されているようですので、再考。

javascriptで、zip圧縮&解凍 - end0tknr's kipple - 新web写経開発

zipファイルをhttp getし、zip解凍後、プレビュー表示 - end0tknr's kipple - 新web写経開発

http://hinata.in/blog/20101003214439.html

今回は、以下のurlから、unzip に zip.js、 SJIS日本語ファイル名のUTF8変換に encoding.js を利用させて頂いています。

https://gildas-lormeau.github.io/zip.js

https://github.com/polygonplanet/encoding.js

以降は実行結果やポイントです

実行結果

f:id:end0tknr:20171228220611p:plain

ディレクトリ構成

$ tree
.
├── index.html
├── encoding.min.js
└── zip_js
    ├── deflate.js
    ├── demo2.js
    ├── inflate.js
    ├── mime-types.js
    ├── zip-ext.js
    ├── zip-fs.js
    ├── zip.js
    └── z-worker.js

html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div id="container">
      <ol id="demo-container">
    <li>
      <label>
        <span class="form-label">choose a zip file</span>
        <input type="file" accept="application/zip" id="file-input">
      </label>
    </li>
    <li>
      <label>
        <span class="form-label">choose temporary storage</span>
        <select id="creation-method-input">
          <option value="Blob">RAM</option>
          <option value="File">HDD</option>
        </select>
      </label>
    </li>
    <li>
      <span class="form-label">download zip content</span>
      <ul id="file-list">
      </ul>
    </li>
      </ol>
    </div>
    <script type="text/javascript" src="./zip_js/zip.js"></script>
    <script type="text/javascript" src="./zip_js/zip-ext.js"></script>
    <script type="text/javascript" src="./zip_js/demo2.js"></script>
    <script type="text/javascript" src="./encoding.min.js"></script>
  </body>
</html>

demo2.js の抜粋 (先頭付近)

fileフォームにファイルを指定すると、ブラウザが z-worker.js 等をhttp getしますが この取得先pathをzip.workerScriptsPath 指定します.

(function(obj) {
    zip.workerScriptsPath = "zip_js/";

zip.js の抜粋 (先頭付近)

windowsでzipを作成する場合、内部のファイル名はsjisですので、 ブラウザに表示する為、 encoding.js で文字コード変換しています。

var filename_bytes =
    Encoding.convert(data.array.subarray(index+46,
                                         index+46+entry.filenameLength),
                    'UNICODE','SJIS');
    entry.filename = getString(filename_bytes);
  //entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);