JSONとCSVのストリーミング
大きなデータに対するjson.Decoderとencoding/csv
「JSONとCSVのストリーミング」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
ストリーミングを使う理由
大きな JSON ファイルや CSV ファイル全体をメモリに読み込むと、ヒープ使用量が大きくなります。ストリーミングではレコードを 1 件ずつ処理するため、ファイルサイズにかかわらずメモリ使用量を一定に保てます。
ストリーミング用の json.Decoder
json.NewDecoder は任意の io.Reader をラップします。Token() で JSON トークンストリームをたどるか、JSON 配列に対してループ内で Decode を使用します。
dec := json.NewDecoder(file)
// consume opening [
for dec.More() {
var record Record
dec.Decode(&record)
process(record)
}配列の開始の検出
デコードループの前に dec.Token() を呼び出して、開き角括弧を読み取ります。
t, _ := dec.Token() // consume [
for dec.More() {
var r Record
dec.Decode(&r)
}HTTP からのストリーミング
レスポンス全体をバッファリングせずに、HTTP レスポンスボディから JSON を直接デコードします。
resp, _ := http.Get(url)
defer resp.Body.Close()
dec := json.NewDecoder(resp.Body)
for dec.More() {
var item Item
dec.Decode(&item)
process(item)
}encoding/csv のリーダー
csv.NewReader は CSV を行単位で読み取ります。実際の CSV にあるさまざまな形式に対応するには、LazyQuotes、TrimLeadingSpace、Comment を設定します。
r := csv.NewReader(file)
for {
record, err := r.Read()
if err == io.EOF { break }
if err != nil { return err }
process(record)
}CSV ヘッダーのスキップ
先頭のレコードを読み取って破棄し、ヘッダー行をスキップします。
r.Read() // discard header
for {
record, err := r.Read()
if err == io.EOF { break }
}csv.Writer
csv.NewWriter を使って CSV を行単位で書き込みます。書き込み後は必ず w.Flush() を呼び出し、w.Error() を確認してください。
w := csv.NewWriter(file)
w.Write([]string{"name", "age"})
w.Flush()
if err := w.Error(); err != nil { return err }カスタム区切り文字
CSV ファイルでは、セミコロンやタブが使われることがあります。r.Comma に目的の rune を設定してください。
r := csv.NewReader(file)
r.Comma = ';' // semicolon-separatedJSON Lines のストリーミング(NDJSON)
改行区切り JSON(1 行に 1 つの JSON オブジェクト)は、ストリーミングに適しています。行単位で読み取り、各行を個別にアンマーシャルします。
scanner := bufio.NewScanner(file)
for scanner.Scan() {
var record Record
json.Unmarshal(scanner.Bytes(), &record)
}メモリ使用量のストリーミング
ストリーミングを使用すると、ヒープ割り当ては O(ファイルサイズ) ではなく O(レコードサイズ) に抑えられます。1 KB のレコードで構成された 1 GB のファイルの場合、メモリに読み込む方法では約 1 GB 必要ですが、ストリーミングでは約 1 KB で済みます。
ストリーミング中のコンテキストキャンセル
デコードループ内で ctx.Done() を確認すると、コンテキストがキャンセルされたときにストリーミングを中断できます。これにより、goroutine が EOF まで読み続けるのを防げます。
for dec.More() {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
dec.Decode(&record)
}確認問題
json.Unmarshal よりも json.Decoder で JSON をストリーミングする利点は何ですか。
まとめ:JSON と CSV のストリーミング
重要なポイント:
- json.Decoder:JSON 配列には dec.More() を使ったループを使用します
- csv.NewReader:行単位で読み込みます。区切り文字を変更するには Comma を設定します
- NDJSON:bufio.Scanner と行ごとの Unmarshal を使用します
- ストリーミングを使うと、ファイルサイズにかかわらずメモリ使用量を一定に保てます
よくある質問
「JSONとCSVのストリーミング」レッスンは無料ですか?
はい。「JSONとCSVのストリーミング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「JSONとCSVのストリーミング」で何を学びますか?
大きなデータに対するjson.Decoderとencoding/csv ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「JSONとCSVのストリーミング」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- osとbufioによるファイル読み込み
- ファイルと一時ファイルへの書き込み
- JSONのエンコードとデコード
- JSONとCSVのストリーミング