nodeでファイルをzip圧縮することがあり、 archiver を使ってみることにしました。
検証用コード
archiver のQuick Startからほぼコピペ
// 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の展開してみたら変更日がズレてる
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時間進めて引数に加えることにしました。
// 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();
})
できたけど...やっぱりプルリク送った方がいいな
時間を作って直してみるか〜