Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책
16270 단어 Go
개시하다
파일과 zip을 Go로 압축하는 방법으로 문제와 회피의 문장을 수반한다.
(더 좋은 방법이 있다면 지적해 주세요.)
실험 환경
go version go1.4.2 darwin/amd64
(Mac OS X)
zip 압축 코드
파일의 zip 압축 코드//ファイルを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
}
파일 zip 압축 호출 사이드 코드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)
}
보통 쓰면 이런 느낌일 거예요.스케줄러:맞지?
참조: http://golang.org/pkg/archive/zip/
실험
이걸로 압축할게요.
보기 흉하다
왼쪽은 원본 파일이고, 오른쪽은 압축된 파일의 시간 스탬프입니다.
시간 스탬프가 다른 거 알아요.
(그리고 마침 9시간 늦었다.)
즉, 위에서 말한 바와 같이, zip.FileInfoHeader를 사용하면 파일 시간이 달라집니다.
원인의 예측
예상일 뿐이지만 탐색해 보자
zip.FileInfoHeader->FileHeader.SetModTime->timeToMsDosTime
http://golang.org/src/archive/zip/struct.go#L170
의t = t.In(time.UTC)
그러나 원본 파일의 시간 스탬프를 표준 시간으로 처리하면 JST와의 차이(9시간)가 늦어진다. 시간TomsDoosTime의 처리가 느리게 계산되기 때문이다.
대응 코드
이거 zip.나는 FileInfoHeader가 문제라고 생각하는데, 밖에서는 아무리 해도 할 수 없을 것 같다.
객체 코드
http://golang.org/src/archive/zip/struct.go#L110
그냥 복사해서 살짝 수정해 주세요.
FileInfoHeader 수정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
}
주석 부분은 개조 부분이다.
로컬 환경의 시차 편이를 가져와 파일의 시간 스탬프에 추가하면 됩니다.
이렇게 되면, zip.FileInfoHeader를 위의 FileInfoHeader로 교체합니다.
첫 번째 코드 변경점 header, _ := FileInfoHeader(info)
//zip用のパスを設定
//これを設定しないと、zip内でディレクトリの中に作られない。
header.Name = zipPath
총결산
zip.FileInfoHeader를 사용하는 동안 잘못된 타임스탬프가 처리되었습니다.
zip.FileInfoHeader(time Toms Doostime)의 버그 같지만, (없을 것 같아) 자신의 잘못된 인식인가요?
덤
지정한 디렉터리를 압축하는 데 사용되는 코드입니다.
디렉터리의 zip 압축 코드//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
}
디렉터리 zip 압축 호출 사이드 코드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)
}
참고 자료
고오 언어로 무압축 zip을 만들고 싶어요.
Reference
이 문제에 관하여(Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuki2006/items/0211421792bd788f8153
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
go version go1.4.2 darwin/amd64
(Mac OS X)
zip 압축 코드
파일의 zip 압축 코드//ファイルを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
}
파일 zip 압축 호출 사이드 코드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)
}
보통 쓰면 이런 느낌일 거예요.스케줄러:맞지?
참조: http://golang.org/pkg/archive/zip/
실험
이걸로 압축할게요.
보기 흉하다
왼쪽은 원본 파일이고, 오른쪽은 압축된 파일의 시간 스탬프입니다.
시간 스탬프가 다른 거 알아요.
(그리고 마침 9시간 늦었다.)
즉, 위에서 말한 바와 같이, zip.FileInfoHeader를 사용하면 파일 시간이 달라집니다.
원인의 예측
예상일 뿐이지만 탐색해 보자
zip.FileInfoHeader->FileHeader.SetModTime->timeToMsDosTime
http://golang.org/src/archive/zip/struct.go#L170
의t = t.In(time.UTC)
그러나 원본 파일의 시간 스탬프를 표준 시간으로 처리하면 JST와의 차이(9시간)가 늦어진다. 시간TomsDoosTime의 처리가 느리게 계산되기 때문이다.
대응 코드
이거 zip.나는 FileInfoHeader가 문제라고 생각하는데, 밖에서는 아무리 해도 할 수 없을 것 같다.
객체 코드
http://golang.org/src/archive/zip/struct.go#L110
그냥 복사해서 살짝 수정해 주세요.
FileInfoHeader 수정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
}
주석 부분은 개조 부분이다.
로컬 환경의 시차 편이를 가져와 파일의 시간 스탬프에 추가하면 됩니다.
이렇게 되면, zip.FileInfoHeader를 위의 FileInfoHeader로 교체합니다.
첫 번째 코드 변경점 header, _ := FileInfoHeader(info)
//zip用のパスを設定
//これを設定しないと、zip内でディレクトリの中に作られない。
header.Name = zipPath
총결산
zip.FileInfoHeader를 사용하는 동안 잘못된 타임스탬프가 처리되었습니다.
zip.FileInfoHeader(time Toms Doostime)의 버그 같지만, (없을 것 같아) 자신의 잘못된 인식인가요?
덤
지정한 디렉터리를 압축하는 데 사용되는 코드입니다.
디렉터리의 zip 압축 코드//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
}
디렉터리 zip 압축 호출 사이드 코드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)
}
참고 자료
고오 언어로 무압축 zip을 만들고 싶어요.
Reference
이 문제에 관하여(Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuki2006/items/0211421792bd788f8153
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
//ファイルを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
}
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)
}
이걸로 압축할게요.
보기 흉하다
왼쪽은 원본 파일이고, 오른쪽은 압축된 파일의 시간 스탬프입니다.
시간 스탬프가 다른 거 알아요.
(그리고 마침 9시간 늦었다.)
즉, 위에서 말한 바와 같이, zip.FileInfoHeader를 사용하면 파일 시간이 달라집니다.
원인의 예측
예상일 뿐이지만 탐색해 보자
zip.FileInfoHeader->FileHeader.SetModTime->timeToMsDosTime
http://golang.org/src/archive/zip/struct.go#L170
의
t = t.In(time.UTC)
그러나 원본 파일의 시간 스탬프를 표준 시간으로 처리하면 JST와의 차이(9시간)가 늦어진다. 시간TomsDoosTime의 처리가 느리게 계산되기 때문이다.대응 코드
이거 zip.나는 FileInfoHeader가 문제라고 생각하는데, 밖에서는 아무리 해도 할 수 없을 것 같다.
객체 코드
http://golang.org/src/archive/zip/struct.go#L110
그냥 복사해서 살짝 수정해 주세요.
FileInfoHeader 수정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
}
주석 부분은 개조 부분이다.
로컬 환경의 시차 편이를 가져와 파일의 시간 스탬프에 추가하면 됩니다.
이렇게 되면, zip.FileInfoHeader를 위의 FileInfoHeader로 교체합니다.
첫 번째 코드 변경점 header, _ := FileInfoHeader(info)
//zip用のパスを設定
//これを設定しないと、zip内でディレクトリの中に作られない。
header.Name = zipPath
총결산
zip.FileInfoHeader를 사용하는 동안 잘못된 타임스탬프가 처리되었습니다.
zip.FileInfoHeader(time Toms Doostime)의 버그 같지만, (없을 것 같아) 자신의 잘못된 인식인가요?
덤
지정한 디렉터리를 압축하는 데 사용되는 코드입니다.
디렉터리의 zip 압축 코드//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
}
디렉터리 zip 압축 호출 사이드 코드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)
}
참고 자료
고오 언어로 무압축 zip을 만들고 싶어요.
Reference
이 문제에 관하여(Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuki2006/items/0211421792bd788f8153
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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
}
header, _ := FileInfoHeader(info)
//zip用のパスを設定
//これを設定しないと、zip内でディレクトリの中に作られない。
header.Name = zipPath
zip.FileInfoHeader를 사용하는 동안 잘못된 타임스탬프가 처리되었습니다.
zip.FileInfoHeader(time Toms Doostime)의 버그 같지만, (없을 것 같아) 자신의 잘못된 인식인가요?
덤
지정한 디렉터리를 압축하는 데 사용되는 코드입니다.
디렉터리의 zip 압축 코드//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
}
디렉터리 zip 압축 호출 사이드 코드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)
}
참고 자료
고오 언어로 무압축 zip을 만들고 싶어요.
Reference
이 문제에 관하여(Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuki2006/items/0211421792bd788f8153
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
//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
}
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)
}
고오 언어로 무압축 zip을 만들고 싶어요.
Reference
이 문제에 관하여(Go로 파일 zip을 압축할 때 시간 스탬프가 빗나가는 문제를 회피하는 정책), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuki2006/items/0211421792bd788f8153텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)