- "1234"のパスワードのかかったzipファイルを引数に与えると実行ファイルと同じディレクトリに1ファイルを展開する。
package main
import (
"bufio"
"flag"
"fmt"
"github.com/yeka/zip"
"io/ioutil"
"log"
"os"
"path/filepath"
)
const password = "1234"
func readline() {
stdin := bufio.NewScanner(os.Stdin)
for stdin.Scan() {
break
}
}
func main() {
// 実行ファイルディレクトリ取得
exe, err := os.Executable()
dirname := filepath.Dir(exe)
fmt.Println(dirname)
// 引数取得
flag.Parse()
args := flag.Args()
fmt.Println(args)
// zipファイルを開く
r, err := zip.OpenReader(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
defer r.Close()
// zipファイルのリストをループ
for _, f := range r.File {
if f.IsEncrypted() {
f.SetPassword(password)
}
r, err := f.Open()
if err != nil {
log.Fatal(err)
}
// ファイルの中身を読み込み
buf, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
defer r.Close()
fmt.Printf("Size of %v: %v byte(s)\n", f.Name, len(buf))
// ファイル書き出し
err = ioutil.WriteFile(filepath.Join(dirname, f.Name), buf, 0644)
if err != nil {
log.Fatal(err)
}
break
}
// 入力待ち
readline()
}
// パスワード付きzipファイル作る
$ zip -e --password=1234 pool.zip pool.pl
adding: pool.pl (deflated 67%)
// go runだとos.Executable()が/tmpになるので展開先が消える
$ go run main.go pool.zip
/tmp/go-build265026491/b001/exe
[pool.zip]
Size of pool.pl: 6140 byte(s)
$ $ ./main pool.zip
ls: cannot access pool.pl: No such file or directory
// Linuxバイナリ作って実行ならOK
$ go build main.go
$ ./main pool.zip
/home/k8uwall/gozip
[pool.zip]
Size of pool.pl: 6140 byte(s)
$ ls pool.pl
pool.pl
// Windowsバイナリ作る
$ GOOS=windows GOARCH=amd64 go build main.go
$ ls main.exe
main.exe
// Windowsでも使える。ファイルを実行ファイルにDropしても動く。
PS C:\Users\k8uwall\Desktop\gozip> .\main.exe pool.zip
C:\Users\k8uwall\Desktop\gozip
[pool.zip]
Size of pool.pl: 6140 byte(s)
- 入力待ちはWindows向けのデバッグ用
- log.Fatalとfmt.Printfどっちかにしないとorz
- フォルダーを含んだファイルが駄目くさい気がする
-
for _, f := range r.File {
の箇所は1ファイルだけ取り出したかったのだけれど、ループ以外の方法がよくわからなかったが時間切れ
参考リンク
Goでflagを使ってコマンドライン引数を扱う - Qiita
Goでflagを使ってコマンドライン引数を扱う - Qiita
Go言語で標準入力 - Qiita
Go で実行ファイルのパスを取得 - Qiita
これは1.8以降