Last active
October 14, 2015 05:01
-
-
Save yuki2006/74a7396f88988e4a44b1 to your computer and use it in GitHub Desktop.
Goでファイルをzip圧縮したときにタイムスタンプがずれる問題の回避策 ref: http://qiita.com/yuki2006/items/0211421792bd788f8153
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
t = t.In(time.UTC) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buf := new(bytes.Buffer) | |
zw := zip.NewWriter(buf) | |
if ferr := ZipDir(zw, "zip_dir", "dir"); ferr != nil { | |
panic(ferr) | |
} | |
if ferr := zw.Close(); ferr != nil { | |
panic(ferr) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//zipPathは、zip上で表現されるパスを指定します。 | |
//targetDirは、圧縮するファイルシステム上のディレクトリのパスを指定します。 | |
func ZipDir(writer *zip.Writer, zipPath string, targetDir string) error { | |
//圧縮するディレクトリをオープンします。 | |
dir, err := os.Open(targetDir) | |
if err != nil { | |
return err | |
} | |
defer dir.Close() | |
//ディレクトリ内のファイル一覧を取得します。 | |
files, err := dir.Readdirnames(-1) | |
if err != nil { | |
return err | |
} | |
for _, fname := range files { | |
if err := ZipFile(writer, zipPath+"/"+fname, targetDir+"/"+fname); err != nil { | |
return err | |
} | |
} | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buf := new(bytes.Buffer) | |
zw := zip.NewWriter(buf) | |
if ferr := ZipFile(zw, "zip_path", "file.txt"); ferr != nil { | |
panic(ferr) | |
} | |
if ferr := zw.Close(); ferr != nil { | |
panic(ferr) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//ファイルをzip圧縮します。 | |
//zipPathは、zip上で表現されるパスを指定します。 | |
//targetFileは、圧縮するファイルシステム上のファイルのパスを指定します。 | |
func ZipFile(writer *zip.Writer, zipPath string, targetFile string) error { | |
f, err := os.Open(targetFile) | |
if err != nil { | |
return err | |
} | |
defer f.Close() | |
body, err := ioutil.ReadAll(f) | |
if err != nil { | |
return err | |
} | |
info , err := os.Stat(targetFile) | |
if err != nil { | |
return err | |
} | |
header, _ := zip.FileInfoHeader(info) | |
//zip用のパスを設定 | |
//これを設定しないと、zip内でディレクトリの中に作られない。 | |
header.Name = zipPath | |
zf, err := writer.CreateHeader(header) | |
if err != nil { | |
return err | |
} | |
if _, err := zf.Write(body); err != nil { | |
return err | |
} | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
header, _ := FileInfoHeader(info) | |
//zip用のパスを設定 | |
//これを設定しないと、zip内でディレクトリの中に作られない。 | |
header.Name = zipPath |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) { | |
size := fi.Size() | |
fh := &zip.FileHeader{ | |
Name: fi.Name(), | |
UncompressedSize64: uint64(size), | |
} | |
// 現在のLocalを取得する。 | |
local := time.Now().Local() | |
//時刻のoffset(秒)を取得する。 | |
_, offset := local.Zone() | |
//ファイルスタンプの時間に時差分を追加する。 | |
fh.SetModTime(fi.ModTime().Add(time.Duration(offset) * time.Second)) | |
fh.SetMode(fi.Mode()) | |
var uintmax = uint32((1 << 32) - 1) | |
if fh.UncompressedSize64 > uint64(uintmax) { | |
fh.UncompressedSize = uintmax | |
} else { | |
fh.UncompressedSize = uint32(fh.UncompressedSize64) | |
} | |
return fh, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment