いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-399 (io.MultiWriterで複数の出力を一括で行う)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。よく忘れるのでここにメモメモ。。。

io.MultiWriter って使っていますか? 意外と利用している人が周りにいないので、ここにメモすることにしました。

入出力処理を実装していると、一つのデータソースを複数の出力に対して処理することが結構あります。

  • 通信データをソケットに流し込んだ後に、通信ログにも書き込んで、使ったデータはgzipで圧縮して保存
  • ファイルに出力してチェックサムも計算する
  • 流れてくるデータを処理しながらログにも出力する(teeコマンドみたいな動作)

などなど。

こういうときに io.MultiWriter さんはとても便利です。

以下、サンプルです。

サンプル

package multiwriter

import (
    "bytes"
    "compress/gzip"
    "encoding/hex"
    "hash/crc32"
    "io"
    "os"

    "github.com/devlights/gomy/output"
)

// GzipAndCrc は、io.MultiWriterを利用してgzip圧縮しながらCRCチェックサムも算出するサンプルです.
//
// # REFERENCES
//
//   - https://pkg.go.dev/io@go1.22.2#MultiWriter
//   - https://pkg.go.dev/hash/crc32@go1.22.2#NewIEEE
//   - https://pkg.go.dev/compress/gzip@go1.22.2#Writer
//   - https://pkg.go.dev/encoding/hex@go1.22.2#Dumper
func GzipAndCrc() error {
    var (
        data   = []byte("hello world こんにちは 世界")
        buf    = new(bytes.Buffer)
        gzipW  = gzip.NewWriter(buf)
        crcW   = crc32.NewIEEE()
        hexW   = hex.Dumper(os.Stdout)
        writer = io.MultiWriter(gzipW, crcW, hexW)
        err    error
    )
    defer gzipW.Close()

    _, err = writer.Write(data)
    if err != nil {
        return err
    }
    hexW.Close()

    output.Stdoutf("[orig]", "%x\n", data)
    output.Stdoutf("[gzip]", "%x\n", buf.Bytes())
    output.Stdoutf("[crc ]", "%x\n", crcW.Sum32())

    return nil

}

実行すると以下のように出力されます。

$ task
task: [build] go build .
task: [run] ./try-golang -onetime

ENTER EXAMPLE NAME: fileio_multiwriter

[Name] "fileio_multiwriter_gzipandcrc"
00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 20 e3 81 93 e3  |hello world ....|
00000010  82 93 e3 81 ab e3 81 a1  e3 81 af 20 e4 b8 96 e7  |........... ....|
00000020  95 8c                                             |..|
[orig]               68656c6c6f20776f726c6420e38193e38293e381abe381a1e381af20e4b896e7958c
[gzip]               1f8b08000000000000ff
[crc ]               6535a281


[Elapsed] 394.39µs

try-golang/examples/basic/fileio/multiwriter/gzip_and_crc.go at main · devlights/try-golang · GitHub

参考情報

https://pkg.go.dev/io@go1.22.2#MultiWriter

https://pkg.go.dev/hash/crc32@go1.22.2#NewIEEE

https://pkg.go.dev/compress/gzip@go1.22.2#Writer

https://pkg.go.dev/encoding/hex@go1.22.2#Dumper

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。