今回扱ったのはarchiveパッケージでarchive/tarとarchive/zipが含まれています。
サンプルコードはgithubにありますのでごらんください。
archiveパッケージの話題に入る前に、「プログラミング言語Goフレーズブック」での質問で、Type Assertionの例で書籍のサンプルを動かすとコンパイルエラーになる。interfaceの型に変えるとコンパイルが通る。という内容のものがありました。
該当のコードは以下のものになります。(以下のコードは修正済みです)
Example構造体がPublicインターフェイスを実装しているかどうかをチェックするために、e.(Public)という書き方をして、Type Assertionを使って確認するべきという趣旨の事が書かれていますが、なぜかコンパイルエラーということで悩みました。一見、正しいようにみえるのですが、Type Assertionの仕様を確認すると、インターフェイスの変数に対して行うもので、そもそも構造体変数に対して行うものではなかった。という結論に至りました。ぱっと見だとすぐに発見できないので、慣れておいた方がいいです。
package typeassertion
type Public interface {
Name() string
}
type Example struct {
name string
}
func (e Example) Nme() string {
//func (e Example) Name() string {
return e.name
}
// func NewExample() Example {
// return Example{"No Name"}
// }
func NewExample() Public {
return Example{"No Name"}
}
func NewExample2() Public {
var p Public
e := Example{"No Name"}
p.(Example)
// e.(Public)
return e
}
次に、本題のarchiveパッケージのサンプルを見ていきました。
まずは、tarのサンプルから。
ポイントは、tarに書き込むための、Writerを生成するために、tar.NewWriter()を呼び出します。引数はio.Writerなので、os.Create()などで、生成したFileを引数にすれば、ファイルに書き込む事ができます。
tar.NewWriter()で受け取ったWriterは必ずClose()してください。MacOSXだと、標準のアーカイブユーティリティで展開できない(エラーが発生する)という現象が出ました。
(ただ、Win版だと発生せず、OSに依らず、Goのプログラムから読み出すと読み出せたりするのですが…)
Writerを生成したら、あとは、Headerを書き、Bodyを書く。という事を繰り返せば、tarが完成します。
反対に、tarを読み出す時は、tar.NewReader()を呼び出し、Readerを生成します。
reader.Next()を呼び出すと、Headerが取れます。その後、readerからbodyを読み出せばファイルが取得できます。説明が雑なのでサンプルコードと一緒にごらんください。
次に、zipのサンプルですが、tarのサンプルを見た後なら、大体同じような構成なので、難しくないと思います。
zipを読み出す時もtarを読み出す時と変わらないので、特に難しくないでしょう。
結果、tarは圧縮するものではないので、容量が変わらないのは良いとして、zipは多少圧縮されるのかな?と思ったらそんなに変化が無く、画像を扱ったからかな?と思いましたが、テキストにすれば変化が出るのでしょうか…。
で、ディレクトリを走査して、大量のテキストをzipに入れようと試みましたが、時間がなく、stackoverflowのサンプルを発見した所で終わりました。ポイントは、path/filepath#Walk()を使って、再帰的に探していくという事になります。
これは、今後の課題になると思います。
次回は、compressパッケージをいじる会になります。
0 件のコメント:
コメントを投稿