Go言語でのファイル読み込み:ioutil.ReadFileの使い方と応用例

Go言語は、そのシンプルさと効率性で多くの開発者に支持されています。本記事では、Go言語におけるファイル操作の基本を学びたい方を対象に、ioutil.ReadFile関数を使用してファイルを一括で読み込む方法を解説します。この関数は、テキストファイルやデータファイルの内容を手軽に扱うために便利なツールです。また、読み込んだデータをどのように処理するかといった具体的な応用例や注意点も取り上げ、初心者から中級者まで役立つ内容を目指します。これにより、Goでのファイル操作の基礎を理解し、応用力を高めることができるでしょう。

目次

`ioutil.ReadFile`とは


ioutil.ReadFileは、Go言語標準ライブラリのio/ioutilパッケージに含まれる関数で、ファイルを簡単に一括で読み込むためのツールです。この関数は、指定したファイルの内容をすべてメモリにロードし、バイトスライスとして返します。

主な特徴

  • 簡潔な使い方: ファイルのオープン、読み込み、クローズの処理を一度に行うため、コードが簡潔になります。
  • エラー処理が容易: 関数呼び出しの結果でエラーを簡単に検出でき、処理の安全性を確保できます。
  • 汎用性: テキストファイルやバイナリファイルなど、さまざまな種類のデータを読み込むことができます。

適用シナリオ

  • 小~中規模のテキストファイルや設定ファイルの読み込み。
  • 簡単なデータ解析やファイル内容の確認。

注意点


ioutil.ReadFileは、すべてのデータを一度にメモリに読み込むため、大容量ファイルには適していません。この場合、ストリーム形式でデータを読み込む方法を検討する必要があります。

次のセクションでは、ioutil.ReadFileの実際の使用方法を具体例を交えて紹介します。

`ioutil.ReadFile`の使い方


ioutil.ReadFileを使用すると、数行のコードで簡単にファイルを読み込むことができます。このセクションでは、基本的なコード例を通じてその使い方を解説します。

基本的なコード例


以下は、テキストファイルを読み込む簡単な例です。

package main

import (
    "fmt"
    "io/ioutil"
    "log"
)

func main() {
    // 読み込みたいファイルのパスを指定
    filePath := "example.txt"

    // `ioutil.ReadFile`でファイルを一括読み込み
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        // エラーが発生した場合の処理
        log.Fatalf("ファイルの読み込みに失敗しました: %v", err)
    }

    // 読み込んだ内容を文字列として出力
    fmt.Println("ファイル内容:")
    fmt.Println(string(content))
}

コードの詳細

  1. ReadFileの呼び出し
  • ioutil.ReadFile(filePath)で、指定したファイルの内容をすべて読み込みます。戻り値は、バイトスライスとエラーです。
  1. エラー処理
  • ファイルが存在しない、または読み取れない場合にエラーが返されます。このエラーを適切に処理することで、プログラムの安定性を確保します。
  1. 内容の出力
  • 読み込んだデータはバイトスライスとして返されますが、string()で文字列に変換して利用するのが一般的です。

実行結果の例


example.txtの内容が次の通りだとします:

Go is a powerful and efficient programming language.

プログラムの実行結果:

ファイル内容:
Go is a powerful and efficient programming language.

次のセクションでは、エラー処理についてより詳しく解説します。ファイル読み込みにおいては、エラーの適切なハンドリングが非常に重要です。

ファイル読み込み時のエラー処理


ファイル読み込み操作では、ファイルの存在、権限、形式などに起因するエラーが発生する可能性があります。Go言語では、エラー処理が重要な役割を果たし、エラーを適切にハンドリングすることで、プログラムの信頼性と安定性を高めることができます。

一般的なエラーとその原因

  1. ファイルが存在しない (os.ErrNotExist)
  • 指定されたパスにファイルが見つからない場合に発生します。
  1. アクセス権限エラー (os.ErrPermission)
  • ファイルへの読み込み権限が不足している場合に発生します。
  1. 読み取り中のエラー
  • ファイルが壊れている、または読み取り途中で問題が発生した場合に発生します。

エラー処理の例


以下は、ioutil.ReadFileを使用した際にエラーを処理する方法の例です。

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
)

func main() {
    filePath := "example.txt"

    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        if os.IsNotExist(err) {
            log.Fatalf("エラー: ファイルが存在しません - %v", err)
        } else if os.IsPermission(err) {
            log.Fatalf("エラー: ファイルへのアクセス権限がありません - %v", err)
        } else {
            log.Fatalf("エラー: ファイルの読み込み中に問題が発生しました - %v", err)
        }
    }

    fmt.Println("ファイルの内容:")
    fmt.Println(string(content))
}

コードの解説

  1. エラー種別の判定
  • os.IsNotExist(err)でファイルの存在を確認します。
  • os.IsPermission(err)で権限エラーを判定します。
  1. 適切なエラーメッセージ
  • エラー内容に応じた具体的なメッセージを出力することで、問題の特定が容易になります。
  1. プログラムの終了
  • log.Fatalfを使用してエラー発生時にプログラムを終了します。実運用では、エラーに応じたリカバリ処理を追加することも可能です。

実行結果の例

  • ファイルが存在しない場合:
  エラー: ファイルが存在しません - open example.txt: no such file or directory
  • 読み取り権限がない場合:
  エラー: ファイルへのアクセス権限がありません - open example.txt: permission denied

次のセクションでは、読み込んだデータをどのようにテキスト処理するかを具体的に解説します。

読み込んだデータのテキスト処理


ファイルの内容を読み込んだ後、そのデータを解析・加工することで、実用的な処理が可能になります。このセクションでは、文字列操作やデータ解析の基本的なテクニックを紹介します。

基本的なテキスト処理の例


以下は、ファイル内容を行単位に分割して処理する例です。

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

func main() {
    filePath := "example.txt"

    // ファイルの読み込み
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        panic(err)
    }

    // バイトスライスを文字列に変換
    text := string(content)

    // 行単位に分割
    lines := strings.Split(text, "\n")

    // 各行を出力
    fmt.Println("ファイル内容 (行ごと):")
    for i, line := range lines {
        fmt.Printf("行 %d: %s\n", i+1, line)
    }
}

コードの詳細

  1. string(content)
  • ioutil.ReadFileが返すバイトスライスを文字列に変換します。
  1. strings.Split
  • ファイルの内容を改行文字で分割し、行ごとに分けます。

特定の単語や文字列を検索


次は、特定の単語を含む行を抽出する例です。

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

func main() {
    filePath := "example.txt"
    targetWord := "Go"

    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        panic(err)
    }

    text := string(content)
    lines := strings.Split(text, "\n")

    fmt.Printf("'%s' を含む行:\n", targetWord)
    for i, line := range lines {
        if strings.Contains(line, targetWord) {
            fmt.Printf("行 %d: %s\n", i+1, line)
        }
    }
}

特長

  • strings.Contains: 文字列が特定の単語を含むか判定します。
  • 条件に一致する行だけを出力することで、効率的な検索が可能です。

文字列の置換処理


次は、特定の単語を別の単語に置き換える例です。

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

func main() {
    filePath := "example.txt"
    oldWord := "Go"
    newWord := "Golang"

    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        panic(err)
    }

    text := string(content)

    // 文字列置換
    modifiedText := strings.ReplaceAll(text, oldWord, newWord)

    fmt.Println("置換後のテキスト:")
    fmt.Println(modifiedText)
}

特長

  • strings.ReplaceAll: 文字列全体で特定の単語を新しい単語に置き換えます。
  • 修正結果を新しいファイルに保存することで、更新処理も可能です。

実行結果の例


元のファイルの内容:

Go is a powerful language.
Go makes development fast and efficient.

各処理の結果:

  1. 行分割:
   行 1: Go is a powerful language.
   行 2: Go makes development fast and efficient.
  1. 単語検索:
   'Go' を含む行:
   行 1: Go is a powerful language.
   行 2: Go makes development fast and efficient.
  1. 置換:
   Golang is a powerful language.
   Golang makes development fast and efficient.

次のセクションでは、大容量ファイルを扱う際の注意点と効率的な処理方法について説明します。

大容量ファイルの処理時の注意点


ioutil.ReadFileは、すべてのデータを一括でメモリに読み込むため、小規模なファイルには非常に便利です。しかし、大容量のファイルを扱う際には、メモリ不足や処理の効率性に注意する必要があります。このセクションでは、大容量ファイルを効率的に処理するためのポイントと代替手法を紹介します。

なぜ大容量ファイルで問題が起きるのか

  1. メモリ消費量の増加
  • ファイル全体をメモリにロードするため、巨大なファイルではメモリ不足やパフォーマンス低下の原因になります。
  1. 操作の非効率性
  • 必要なデータが一部だけの場合でも、全体をロードしてしまうため、処理が無駄に重くなります。

効率的な処理方法

1. `os`パッケージを使用した逐次読み込み


osパッケージを使用すれば、ファイルをストリーム形式で逐次読み込むことができます。

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    filePath := "largefile.txt"

    // ファイルをオープン
    file, err := os.Open(filePath)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // スキャナーを使用して行ごとに処理
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        // 各行を処理
        fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        fmt.Printf("エラー: %v\n", err)
    }
}

コードの特長

  • 逐次処理: メモリに負担をかけず、ファイルを行単位で処理できます。
  • 柔軟性: 条件に応じた行抽出やデータ加工が可能です。

2. バイト単位での読み込み (`os.File.Read`)


バイナリデータや細かい制御が必要な場合は、バイト単位でファイルを読み込む方法も有効です。

package main

import (
    "fmt"
    "os"
)

func main() {
    filePath := "largefile.bin"

    // ファイルをオープン
    file, err := os.Open(filePath)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    buffer := make([]byte, 1024) // 1KBのバッファ
    for {
        // バッファに読み込む
        bytesRead, err := file.Read(buffer)
        if err != nil {
            if err.Error() == "EOF" {
                break // ファイルの終わり
            }
            panic(err)
        }
        fmt.Println("読み込みデータ:", buffer[:bytesRead])
    }
}

コードの特長

  • カスタムバッファサイズ: 必要に応じてバッファサイズを調整可能。
  • 柔軟な読み込み: 特定のサイズで区切って読み込む用途に適しています。

大容量データの並列処理


大容量データを処理する際、並列処理を活用するとパフォーマンスが向上します。以下は、複数のゴルーチンを使用してファイルを分割処理する例です。

package main

import (
    "fmt"
    "io"
    "os"
    "sync"
)

func main() {
    filePath := "largefile.txt"
    file, err := os.Open(filePath)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    const chunkSize = 1024 * 1024 // 1MB
    var wg sync.WaitGroup

    for {
        // チャンクを読み込む
        buffer := make([]byte, chunkSize)
        bytesRead, err := file.Read(buffer)
        if err != nil {
            if err == io.EOF {
                break
            }
            panic(err)
        }

        // ゴルーチンで並列処理
        wg.Add(1)
        go func(data []byte) {
            defer wg.Done()
            fmt.Printf("処理中: %d バイト\n", len(data))
        }(buffer[:bytesRead])
    }

    wg.Wait()
    fmt.Println("すべてのチャンクが処理されました。")
}

実行時の注意点

  • メモリとスレッド管理: 並列処理でのリソース管理に注意し、過剰なゴルーチンの生成を避けましょう。
  • ファイルの分割: 事前に分割可能なデータ構造の場合、処理をさらに最適化できます。

まとめ


大容量ファイルを扱う際には、ioutil.ReadFileのような一括読み込みではなく、逐次処理や並列処理を用いることで効率的かつ安全にデータを扱うことができます。次のセクションでは、osパッケージとの比較を通じて、使い分けの基準を明確にします。

`ioutil.ReadFile`と`os`パッケージとの比較


Go言語には複数の方法でファイルを操作する機能があり、ioutil.ReadFileosパッケージはそれぞれ異なる特徴を持っています。このセクションでは、両者を比較し、使い分けの基準を明確にします。

`ioutil.ReadFile`の特徴

  1. シンプルなAPI
  • 一行のコードでファイルを読み込むことができるため、初心者に適した簡潔な方法です。
  1. 一括読み込み
  • ファイル全体をメモリにロードします。小~中規模のファイルには最適ですが、大容量ファイルには不向きです。
  1. 用途
  • 設定ファイルや小規模なデータファイルの読み取りに適しています。

使用例


以下のコードは、ioutil.ReadFileを用いてファイル内容を一括で読み込む例です。

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    content, err := ioutil.ReadFile("example.txt")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(content))
}

`os`パッケージの特徴

  1. 低レベルな制御
  • ファイルのオープン、読み込み、クローズを個別に行うことで、ファイル操作を細かく制御できます。
  1. 逐次読み込みが可能
  • バッファを使用して部分的にデータを読み込むため、大容量ファイルの処理に適しています。
  1. 用途
  • ログファイルやバイナリデータ、ストリーム処理など、高度なファイル操作が必要な場合に適しています。

使用例


以下は、osパッケージを用いてファイルを逐次的に読み込む例です。

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        fmt.Printf("エラー: %v\n", err)
    }
}

主な比較

特徴ioutil.ReadFileosパッケージ
使いやすさシンプル、初心者向け柔軟、高度な制御が可能
メモリ消費ファイル全体をメモリに読み込む必要な部分だけを逐次的に読み込む
パフォーマンス小規模ファイル向け大規模ファイル向け
応用性基本的なテキストデータ処理に最適ログ解析やバイナリ操作などにも対応

使い分けの基準

  • 小規模なテキストファイル
  • ioutil.ReadFileを使用して簡単に処理できます。
  • 大容量ファイル
  • osパッケージを利用して、効率的にデータを逐次処理します。
  • 柔軟な操作が必要な場合
  • ファイルの特定の部分を読み書きする場合やストリーム処理を行う場合は、osパッケージが適しています。

まとめ


ioutil.ReadFileは、簡潔さと使いやすさを重視した選択肢で、小規模なファイルの処理に適しています。一方、osパッケージは柔軟で効率的な処理を可能にし、大規模ファイルや高度な操作が必要な場面で活躍します。次のセクションでは、応用例としてCSVデータの処理を具体的に解説します。

応用例:CSVデータの処理


CSV(Comma Separated Values)は、データ交換や保存に広く利用される形式です。Goでは、ioutil.ReadFileでCSVファイルを読み込んだ後、解析や加工を簡単に行うことができます。このセクションでは、CSVデータの処理例を紹介します。

CSVデータの例


以下のようなサンプルデータを持つCSVファイルdata.csvを処理する例を考えます。

Name,Age,Occupation
Alice,30,Engineer
Bob,25,Designer
Charlie,35,Manager

基本的なCSVファイルの読み込み

package main

import (
    "encoding/csv"
    "fmt"
    "io/ioutil"
    "log"
    "strings"
)

func main() {
    filePath := "data.csv"

    // ファイルを読み込む
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatalf("ファイル読み込みエラー: %v", err)
    }

    // ファイル内容を文字列として変換
    reader := csv.NewReader(strings.NewReader(string(content)))

    // CSVを解析
    records, err := reader.ReadAll()
    if err != nil {
        log.Fatalf("CSV解析エラー: %v", err)
    }

    // 解析結果を表示
    for i, record := range records {
        if i == 0 {
            fmt.Println("ヘッダー:", record)
        } else {
            fmt.Printf("行 %d: 名前=%s, 年齢=%s, 職業=%s\n", i, record[0], record[1], record[2])
        }
    }
}

コードの解説

  1. ioutil.ReadFileでデータを読み込み
  • ファイルの内容をバイトスライスとして取得し、文字列に変換します。
  1. csv.NewReaderを使用
  • 文字列をCSV形式として解析するために、新しいCSVリーダーを作成します。
  1. ReadAllでCSV全体を読み込む
  • ReadAllはすべての行を読み込んで2次元スライスとして返します。

特定列のデータ抽出


CSVデータから特定の列だけを抽出する例です。

package main

import (
    "encoding/csv"
    "fmt"
    "io/ioutil"
    "log"
    "strings"
)

func main() {
    filePath := "data.csv"

    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatalf("ファイル読み込みエラー: %v", err)
    }

    reader := csv.NewReader(strings.NewReader(string(content)))

    records, err := reader.ReadAll()
    if err != nil {
        log.Fatalf("CSV解析エラー: %v", err)
    }

    // 年齢列 (2番目) を抽出
    fmt.Println("年齢列:")
    for i, record := range records {
        if i == 0 {
            continue // ヘッダーをスキップ
        }
        fmt.Printf("行 %d: 年齢=%s\n", i, record[1])
    }
}

結果の例

年齢列:
行 1: 年齢=30
行 2: 年齢=25
行 3: 年齢=35

データの加工と再保存


CSVデータを加工し、新しいファイルとして保存する例です。

package main

import (
    "encoding/csv"
    "fmt"
    "os"
)

func main() {
    records := [][]string{
        {"Name", "Age", "Occupation"},
        {"Alice", "30", "Engineer"},
        {"Bob", "25", "Designer"},
        {"Charlie", "35", "Manager"},
    }

    // 新しいCSVファイルに書き込む
    outputFile, err := os.Create("output.csv")
    if err != nil {
        panic(err)
    }
    defer outputFile.Close()

    writer := csv.NewWriter(outputFile)
    defer writer.Flush()

    for _, record := range records {
        if err := writer.Write(record); err != nil {
            panic(err)
        }
    }

    fmt.Println("CSVデータが output.csv に保存されました。")
}

まとめ


CSVデータの処理では、ioutil.ReadFileを用いたデータの読み込みと、encoding/csvパッケージを組み合わせることで、簡単かつ柔軟な操作が可能です。特定列の抽出、データ加工、再保存など、多様なニーズに対応できます。次のセクションでは、JSONデータの処理方法について解説します。

応用例:JSONデータの処理


JSON(JavaScript Object Notation)は、API通信や設定ファイルなどで広く使用される軽量データ形式です。Goでは、ioutil.ReadFileを使用してJSONファイルを読み込み、encoding/jsonパッケージを活用して解析することが可能です。このセクションでは、JSONデータの処理例を解説します。

JSONデータの例


以下のようなサンプルJSONデータを含むdata.jsonファイルを使用します。

{
  "users": [
    { "name": "Alice", "age": 30, "occupation": "Engineer" },
    { "name": "Bob", "age": 25, "occupation": "Designer" },
    { "name": "Charlie", "age": 35, "occupation": "Manager" }
  ]
}

JSONデータを読み込む

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
)

type User struct {
    Name       string `json:"name"`
    Age        int    `json:"age"`
    Occupation string `json:"occupation"`
}

type UsersData struct {
    Users []User `json:"users"`
}

func main() {
    filePath := "data.json"

    // ファイルを読み込む
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatalf("ファイル読み込みエラー: %v", err)
    }

    // JSONを構造体に変換
    var data UsersData
    if err := json.Unmarshal(content, &data); err != nil {
        log.Fatalf("JSON解析エラー: %v", err)
    }

    // データを表示
    fmt.Println("ユーザー情報:")
    for _, user := range data.Users {
        fmt.Printf("名前: %s, 年齢: %d, 職業: %s\n", user.Name, user.Age, user.Occupation)
    }
}

コードの解説

  1. 構造体の定義
  • JSONの構造に合わせてUserUsersData構造体を定義します。タグ(例: json:"name")はJSONフィールド名とGoのフィールド名をマッピングします。
  1. JSONのデコード
  • json.Unmarshal関数を使い、JSONデータをGoの構造体にデコードします。
  1. データの利用
  • デコードされたデータは通常のGo構造体として操作できるため、データ処理が容易です。

特定データの抽出


以下は、30歳以上のユーザーを抽出する例です。

for _, user := range data.Users {
    if user.Age >= 30 {
        fmt.Printf("名前: %s, 年齢: %d, 職業: %s\n", user.Name, user.Age, user.Occupation)
    }
}

JSONデータの更新と保存


以下は、JSONデータを更新して新しいファイルに保存する例です。

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "os"
)

func main() {
    filePath := "data.json"

    // ファイルを読み込む
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        log.Fatalf("ファイル読み込みエラー: %v", err)
    }

    var data UsersData
    if err := json.Unmarshal(content, &data); err != nil {
        log.Fatalf("JSON解析エラー: %v", err)
    }

    // 新しいユーザーを追加
    newUser := User{Name: "Dave", Age: 28, Occupation: "Developer"}
    data.Users = append(data.Users, newUser)

    // 更新されたデータをJSONにエンコード
    updatedContent, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        log.Fatalf("JSONエンコードエラー: %v", err)
    }

    // 新しいファイルに保存
    if err := ioutil.WriteFile("updated_data.json", updatedContent, 0644); err != nil {
        log.Fatalf("ファイル保存エラー: %v", err)
    }

    fmt.Println("データが更新され、保存されました。")
}

コードの解説

  1. JSONエンコード
  • json.MarshalIndentを使用して、読みやすい形式(インデント付き)でJSONにエンコードします。
  1. ファイルの保存
  • ioutil.WriteFileを使用して、エンコードされたJSONデータを新しいファイルに書き込みます。

実行結果の例


更新されたファイルupdated_data.jsonの内容:

{
  "users": [
    { "name": "Alice", "age": 30, "occupation": "Engineer" },
    { "name": "Bob", "age": 25, "occupation": "Designer" },
    { "name": "Charlie", "age": 35, "occupation": "Manager" },
    { "name": "Dave", "age": 28, "occupation": "Developer" }
  ]
}

まとめ


JSONデータの処理では、ioutil.ReadFileencoding/jsonを組み合わせることで、データの読み込み、解析、加工、保存が効率的に行えます。これにより、API通信や設定管理、データ操作など、多様なシナリオに対応可能です。次のセクションでは、演習問題を通じてこれらの内容を実践的に復習します。

演習問題


以下は、この記事で学んだ内容を活用して、実践的なスキルを身につけるための演習問題です。Goコードを書いて実行してみてください。

問題1: CSVデータの特定条件による抽出


以下のようなCSVファイルpeople.csvを読み込み、30歳以上の人々のデータを抽出してコンソールに表示してください。

CSV内容: people.csv

Name,Age,City
Alice,30,New York
Bob,25,Los Angeles
Charlie,35,Chicago
Dave,28,San Francisco
Eve,40,Seattle

期待する出力

名前: Alice, 年齢: 30, 都市: New York
名前: Charlie, 年齢: 35, 都市: Chicago
名前: Eve, 年齢: 40, 都市: Seattle

ヒント:

  • ioutil.ReadFileでCSVファイルを読み込みます。
  • encoding/csvパッケージでデータを解析します。
  • 条件に一致する行だけを抽出します。

問題2: JSONデータのフィルタリングと保存


以下のようなJSONファイルproducts.jsonから、価格(price)が50以上の商品を抽出し、新しいJSONファイルfiltered_products.jsonに保存してください。

JSON内容: products.json

{
  "products": [
    { "id": 1, "name": "Laptop", "price": 1000 },
    { "id": 2, "name": "Mouse", "price": 25 },
    { "id": 3, "name": "Keyboard", "price": 75 },
    { "id": 4, "name": "Monitor", "price": 150 },
    { "id": 5, "name": "Pen", "price": 5 }
  ]
}

期待する出力ファイル: filtered_products.json

{
  "products": [
    { "id": 1, "name": "Laptop", "price": 1000 },
    { "id": 3, "name": "Keyboard", "price": 75 },
    { "id": 4, "name": "Monitor", "price": 150 }
  ]
}

ヒント:

  • json.UnmarshalでデータをGo構造体に変換します。
  • 条件を満たすデータだけをフィルタリングします。
  • json.MarshalIndentでJSONデータとして保存します。

問題3: 大容量テキストファイルの処理


100万行のテキストデータを持つファイルlargefile.txtから、特定のキーワード(例: ERROR)を含む行を抽出し、別のファイルerrors.txtに保存してください。

ヒント:

  • osパッケージとbufio.Scannerを使用して、行単位でファイルを読み込みます。
  • 条件を満たす行だけを新しいファイルに書き込みます。

まとめ


これらの演習を通じて、ioutil.ReadFileを使用したファイル操作と、データ解析・加工のスキルを強化することができます。各問題に取り組むことで、Goでの効率的なファイル処理の基礎が確実に身につくでしょう。

まとめ


本記事では、Go言語におけるioutil.ReadFileを使用したファイル操作の基本から応用までを解説しました。ioutil.ReadFileを使ったシンプルなファイル読み込み方法、大容量ファイル処理時の注意点、CSVやJSONデータの解析、そして実用的な演習問題を通じて、ファイル操作の幅広い実践例を学びました。

適切な方法を選択することで、効率的かつ安全にデータを処理できます。今後は、この記事で学んだ知識を活用して、プロジェクトでの課題解決やデータ処理の効率化に取り組んでください。Go言語のファイル操作の理解を深める第一歩となれば幸いです。

コメント

コメントする

目次