1つのファイルのフルパスは3パーツに分かれる:
gs://example-bucket / tenant-a/Sales/ / 2026-06-01.csv
└─ bucket ───┘ └─ prefix ──┘ └─ ファイル名 ─┘
| パーツ | 役割 | どこから来る |
|---|---|---|
| bucket | 一番外側の入れ物 | コードで別引数として渡す |
| prefix | バケット内の「どの引き出しを開けるか」 | 自分で組み立てる |
| ファイル名 | 引き出しの中身 | 一覧した結果として返ってくる |
重要なのは、Cloud Storage に本当は「フォルダ」が無いこと。prefix はオブジェクト名の前方一致フィルタにすぎない。tenant-a/Sales/ は「この文字列で始まる名前のオブジェクトを全部ちょうだい」という意味になる。
prefix の役割は「どの引き出しを開けるか」であって「中の何を取るか」ではない。中身(ファイル名)は開けた後の一覧で分かる。
prefix は目的のファイル群が入っているフォルダ階層までを指定する。それ以上でも以下でもない。
tenant-a/ だけだと、将来 tenant-a/Stock/ のような別データが混ざる。source まで付けて「テナント × データ種別」で1グループに切り出す。// bucket は別引数。prefix にバケット名は含めない
prefix := fmt.Sprintf("%s/%s/", tenant, source) // 例: tenant-a/Sales/
objects, _ := gcs.ListObjects(ctx, bucket, prefix)
末尾の / が地味に効く。tenant-a/Sales(スラッシュ無し)は前方一致なので tenant-a/Sales2024/ や tenant-a/SalesBackup/ まで巻き込む。/ を付けて「Sales 直下」に限定する。