今回扱ったのは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 件のコメント:
コメントを投稿