LoginSignup
5
2

More than 5 years have passed since last update.

NodeでArchiverを使ったzip圧縮方法と変更日がUTCになるバク対応

Last updated at Posted at 2018-11-11

nodeでファイルをzip圧縮することがあり、 archiver を使ってみることにしました。

検証用コード

archiver のQuick Startからほぼコピペ

Main.js
// require modules
var fs = require('fs');
var archiver = require('archiver');

// create a file to stream archive data to.
var output = fs.createWriteStream(__dirname + '/example.zip');
var archive = archiver('zip', {
  zlib: { level: 9 } // Sets the compression level.
});
output.on('close', () => {
  console.log(archive.pointer() + ' total bytes');
  console.log('archiver has been finalized and the output file descriptor has closed.');
});
output.on('end', () => {
    console.log('Data has been drained');
}); 
archive.on('warning', (err) =>  {throw err;});
archive.on('error',  (err) =>  {throw err;});
archive.pipe(output);
// 圧縮対象ファイル
var file1 = __dirname + '/file1.txt';
archive.append(fs.createReadStream(file1), { name: 'file1.txt' });
archive.finalize();

あっさり成功

デバッグコンソール
247 total bytes
archiver has been finalized and the output file descriptor has closed.

と思いきや....

example.zipの展開してみたら変更日がズレてる

スクリーンショット.png
file1.txt:圧縮前のファイル
file1 2.txt:展開後のファイル

GitHubのissues調べたら出てきた
https://github.com/archiverjs/node-archiver/issues/279

so with zip there is no concept of timezone. archiver is potentially getting back a UTC time from fs.stat which is why you see this. we at one point tried to force local timezones in another part of the code but i think we came back not altering the timezone at all.

zipにはタイムゾーンの概念はない。アーカイバは潜在的にfs.statからUTC時刻を取得しています。ある時点で、コードの別の部分にローカルタイムゾーンを強制しようとしましたが、私たちはタイムゾーンをまったく変更していないと思います。

プルリク送るのがベストなんだけど、暫定対処としてfs.statの変更日を9時間進めて引数に加えることにしました。

Main.js(変更後)
// require modules
var fs = require('fs');
var archiver = require('archiver');

// create a file to stream archive data to.
var output = fs.createWriteStream(__dirname + '/example.zip');
var archive = archiver('zip', {
  zlib: { level: 9 } // Sets the compression level.
});
output.on('close', () => {
  console.log(archive.pointer() + ' total bytes');
  console.log('archiver has been finalized and the output file descriptor has closed.');
});
output.on('end', () => {
    console.log('Data has been drained');
}); 
archive.on('warning', (err) =>  {throw err;});
archive.on('error',  (err) =>  {throw err;});
archive.pipe(output);
// 圧縮対象ファイル
var file1 = __dirname + '/file1.txt';
// fs.statでファイル情報を取得する
fs.stat(file1,(err,stat)=>{
  if(err){
    throw err;
  }
  // 変更日
  let modifyDate = new Date(stat.mtime);
  // 【暫定対処】UTC換算で9時間ズレるから進めておく
  modifyDate.setHours(modifyDate.getHours() + 9);
  stat.mtime = modifyDate;
  // fs.statを引数に加えて変更日がズレないようにする。
  archive.append(fs.createReadStream(file1), { name: 'file1.txt',stats:stat });
  archive.finalize();
})

結果
スクリーンショット 2018-11-11 14.24.07.png

できたけど...やっぱりプルリク送った方がいいな
時間を作って直してみるか〜

5
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2