0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Goでファイル操作ばかりしてる俺が語る!爆速7フォーマット実践サンプル【JSON/YAML/CSV/txt/Excel/ini/XML】

Last updated at Posted at 2025-03-31

はじめに

現在の部署に入ってから、Goでのファイル操作ばかりを行なっているので、この記事では、Goでの色々なファイルの読み書きについて説明します。

JSON

inputファイル

input.json
{
    "name": "John",
    "age": 30
}

読み込みサンプルコード

main.go
package main

import (
	"encoding/json" // JSONエンコード/デコード用パッケージ
	"fmt"           // フォーマット済み入出力用パッケージ
	"log"           // ログ出力用パッケージ
	"os"            // ファイル操作などのOS機能用パッケージ
)

// User構造体はJSONデータのユーザー情報を表現します
type User struct {
	Name string `json:"name"` // JSONの"name"キーに対応
	Age  int    `json:"age"`  // JSONの"age"キーに対応
}

const filePath = "input.json" // 読み込むJSONファイルのパス

func main() {
	// 読み込み専用でファイルをオープン
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err) // エラー発生時はログ出力して終了
	}
	defer file.Close() // 関数終了時にファイルを必ずクローズ

	var user User
	// JSONデコーダーでファイルの内容をUser構造体にデコード
	if err := json.NewDecoder(file).Decode(&user); err != nil {
		log.Fatal(err) // デコードエラーがあればログ出力して終了
	}

	// デコードしたユーザー情報を出力
	fmt.Printf("%+v\n", user) // {Name:John Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"encoding/json" // JSONのエンコード/デコード用パッケージ
	"log"           // エラーログ出力用パッケージ
	"os"            // ファイル操作などのOS機能用パッケージ
)

// User構造体はユーザー情報を保持します
type User struct {
	Name string `json:"name"` // JSONの"name"キーに対応
	Age  int    `json:"age"`  // JSONの"age"キーに対応
}

const filePath = "output.json" // 出力ファイルのパス

func main() {
	// 書き込み可能な状態でファイルをオープン(存在しなければ作成、存在すれば内容を上書き)
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err) // エラー発生時はログ出力して終了
	}
	defer file.Close() // 関数終了時にファイルを必ずクローズ

	// 書き込むユーザー情報を定義
	user := User{
		Name: "John",
		Age:  30,
	}

	// json.Encoderを使って、ユーザー情報をJSON形式でファイルに書き込む
	if err := json.NewEncoder(file).Encode(user); err != nil {
		log.Fatal(err) // エンコードまたは書き込みエラーの場合、ログ出力して終了
	}
}

YAML

inputファイル

input.yaml
name: John
age: 30

読み込みサンプルコード

main.go
package main

import (
	"fmt"           // フォーマット済み入出力用パッケージ
	"log"           // ログ出力用パッケージ
	"os"            // ファイル操作用パッケージ
	"gopkg.in/yaml.v3" // YAMLエンコード/デコード用パッケージ
)

// User構造体はYAMLデータのユーザー情報を表現します
type User struct {
	Name string `yaml:"name"` // YAMLの"name"キーに対応
	Age  int    `yaml:"age"`  // YAMLの"age"キーに対応
}

const filePath = "input.yaml" // 読み込むYAMLファイルのパス

func main() {
	// 読み込み専用でファイルをオープン
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	var user User
	// YAMLデコーダーでファイルの内容をUser構造体にデコード
	if err := yaml.NewDecoder(file).Decode(&user); err != nil {
		log.Fatal(err)
	}

	// デコードしたユーザー情報を出力
	fmt.Printf("%+v\n", user) // {Name:John Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"log"           // エラーログ出力用パッケージ
	"os"            // ファイル操作用パッケージ
	"gopkg.in/yaml.v3" // YAMLエンコード/デコード用パッケージ
)

// User構造体はユーザー情報を保持します
type User struct {
	Name string `yaml:"name"` // YAMLの"name"キーに対応
	Age  int    `yaml:"age"`  // YAMLの"age"キーに対応
}

const filePath = "output.yaml" // 書き込み先のYAMLファイルパス

func main() {
	// 書き込み可能な状態でファイルをオープン(存在しなければ作成、存在すれば上書き)
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	user := User{
		Name: "John",
		Age:  30,
	}

	// YAMLエンコーダーを使って、ユーザー情報をYAML形式でファイルに書き込む
	if err := yaml.NewEncoder(file).Encode(user); err != nil {
		log.Fatal(err)
	}
}

CSV

inputファイル

input.csv
Name,Age
John,30

読み込みサンプルコード

main.go
package main

import (
	"encoding/csv" // CSVデコード用パッケージ
	"fmt"        // フォーマット済み入出力用パッケージ
	"log"        // ログ出力用パッケージ
	"os"         // ファイル操作用パッケージ
	"strconv"    // 文字列⇔数値変換用パッケージ
)

// User構造体はCSVデータのユーザー情報を表現します
type User struct {
	Name string
	Age  int
}

const filePath = "input.csv" // 読み込むCSVファイルのパス

func main() {
	// 読み込み専用でCSVファイルをオープン
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	// ヘッダー行を除き、2行目のレコードをUser構造体に変換(例として)
	if len(records) < 2 {
		log.Fatal("レコードが不足しています")
	}
	age, err := strconv.Atoi(records[1][1])
	if err != nil {
		log.Fatal(err)
	}
	user := User{
		Name: records[1][0],
		Age:  age,
	}

	// 読み込んだユーザー情報を出力
	fmt.Printf("%+v\n", user) // {Name:John Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"encoding/csv" // CSVエンコード用パッケージ
	"log"        // ログ出力用パッケージ
	"os"         // ファイル操作用パッケージ
	"strconv"    // 数値を文字列に変換するためのパッケージ
)

// User構造体はユーザー情報を保持します
type User struct {
	Name string
	Age  int
}

const filePath = "output.csv" // 書き込み先のCSVファイルパス

func main() {
	// 書き込み可能な状態でCSVファイルをオープン(存在しなければ作成、存在すれば上書き)
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

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

	// ヘッダー行の書き込み
	if err := writer.Write([]string{"Name", "Age"}); err != nil {
		log.Fatal(err)
	}

	user := User{
		Name: "John",
		Age:  30,
	}
	// ユーザー情報の書き込み
	record := []string{user.Name, strconv.Itoa(user.Age)}
	if err := writer.Write(record); err != nil {
		log.Fatal(err)
	}
}

txt

inputファイル

input.txt
John
30

読み込みサンプルコード

main.go
package main

import (
	"bufio"    // バッファ付き入出力用パッケージ
	"fmt"      // フォーマット済み入出力用パッケージ
	"log"      // ログ出力用パッケージ
	"os"       // ファイル操作用パッケージ
	"strconv"  // 文字列⇔数値変換用パッケージ
)

const filePath = "input.txt" // 読み込むテキストファイルのパス

func main() {
	// 読み込み専用でテキストファイルをオープン
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	var lines []string
	// 1行ずつ読み込み
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	// 入力ファイルは2行あることを想定(1行目: Name、2行目: Age)
	if len(lines) < 2 {
		log.Fatal("入力ファイルの行数が不足しています")
	}

	name := lines[0]
	age, err := strconv.Atoi(lines[1])
	if err != nil {
		log.Fatal(err)
	}

	// 読み込んだユーザー情報を出力
	fmt.Printf("{Name:%s, Age:%d}\n", name, age) // {Name:John, Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"bufio" // バッファ付き入出力用パッケージ
	"log"   // ログ出力用パッケージ
	"os"    // ファイル操作用パッケージ
)

const filePath = "output.txt" // 書き込み先のテキストファイルパス

func main() {
	// 書き込み可能な状態でテキストファイルをオープン(存在しなければ作成、存在すれば上書き)
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	writer := bufio.NewWriter(file)
	// ユーザー情報 "John" と "30" を1行ずつ書き込む
	if _, err := writer.WriteString("John\n"); err != nil {
		log.Fatal(err)
	}
	if _, err := writer.WriteString("30\n"); err != nil {
		log.Fatal(err)
	}
	writer.Flush()
}

Excel

inputファイル

input.xlsx

Name Age
John 30

このテーブルは、シート "Sheet1" の以下のセルに対応します:

  • セル A1: Name
  • セル B1: Age
  • セル A2: John
  • セル B2: 30

読み込みサンプルコード

main.go
package main

import (
	"fmt"       // フォーマット済み入出力用パッケージ
	"log"       // ログ出力用パッケージ
	"strconv"   // 文字列⇔数値変換用パッケージ
	"github.com/xuri/excelize/v2" // Excel操作用パッケージ
)

const filePath = "input.xlsx" // 読み込むExcelファイルのパス

func main() {
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		log.Fatal(err)
	}
	// シート "Sheet1" のセルから値を取得
	name, err := f.GetCellValue("Sheet1", "A2")
	if err != nil {
		log.Fatal(err)
	}
	ageStr, err := f.GetCellValue("Sheet1", "B2")
	if err != nil {
		log.Fatal(err)
	}
	age, err := strconv.Atoi(ageStr)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("{Name:%s, Age:%d}\n", name, age) // {Name:John, Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"log" // ログ出力用パッケージ
	"github.com/xuri/excelize/v2" // Excel操作用パッケージ
)

const filePath = "output.xlsx" // 書き込み先のExcelファイルパス

func main() {
	f := excelize.NewFile()
	// 新しいシート "Sheet1" を作成
	sheetName := "Sheet1"
	index := f.NewSheet(sheetName)
	// ヘッダーの書き込み
	f.SetCellValue(sheetName, "A1", "Name")
	f.SetCellValue(sheetName, "B1", "Age")
	// ユーザー情報の書き込み
	f.SetCellValue(sheetName, "A2", "John")
	f.SetCellValue(sheetName, "B2", 30)
	// アクティブなシートを設定
	f.SetActiveSheet(index)
	// Excelファイルを保存
	if err := f.SaveAs(filePath); err != nil {
		log.Fatal(err)
	}
}

ini

inputファイル

input.ini
[User]
Name = John
Age = 30

読み込みサンプルコード

main.go
package main

import (
	"fmt"        // フォーマット済み入出力用パッケージ
	"log"        // ログ出力用パッケージ
	"gopkg.in/ini.v1" // INIファイル操作用パッケージ
)

const filePath = "input.ini" // 読み込むINIファイルのパス

func main() {
	cfg, err := ini.Load(filePath)
	if err != nil {
		log.Fatal(err)
	}
	name := cfg.Section("User").Key("Name").String()
	age, err := cfg.Section("User").Key("Age").Int()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("{Name:%s, Age:%d}\n", name, age)
}

書き込みサンプルコード

main.go
package main

import (
	"log"        // ログ出力用パッケージ
	"gopkg.in/ini.v1" // INIファイル操作用パッケージ
)

const filePath = "output.ini" // 書き込み先のINIファイルパス

func main() {
	cfg := ini.Empty()
	sec, err := cfg.NewSection("User")
	if err != nil {
		log.Fatal(err)
	}
	sec.NewKey("Name", "John")
	sec.NewKey("Age", "30")
	if err := cfg.SaveTo(filePath); err != nil {
		log.Fatal(err)
	}
}

XML

inputファイル

input.xml
<?xml version="1.0" encoding="UTF-8"?>
<User>
    <Name>John</Name>
    <Age>30</Age>
</User>

読み込みサンプルコード

main.go
package main

import (
	"encoding/xml" // XMLエンコード/デコード用パッケージ
	"fmt"         // フォーマット済み入出力用パッケージ
	"log"         // ログ出力用パッケージ
	"os"          // ファイル操作用パッケージ
)

// User構造体はXMLデータのユーザー情報を表現します
type User struct {
	XMLName xml.Name `xml:"User"`
	Name    string   `xml:"Name"`
	Age     int      `xml:"Age"`
}

const filePath = "input.xml" // 読み込むXMLファイルのパス

func main() {
	// 読み込み専用でXMLファイルをオープン
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	var user User
	// XMLデコーダーでファイルの内容をUser構造体にデコード
	if err := xml.NewDecoder(file).Decode(&user); err != nil {
		log.Fatal(err)
	}
	// デコードしたユーザー情報を出力
	fmt.Printf("%+v\n", user) // {XMLName:{Space: Local:User} Name:John Age:30}
}

書き込みサンプルコード

main.go
package main

import (
	"encoding/xml" // XMLエンコード/デコード用パッケージ
	"log"         // ログ出力用パッケージ
	"os"          // ファイル操作用パッケージ
)

// User構造体はユーザー情報を保持します
type User struct {
	XMLName xml.Name `xml:"User"`
	Name    string   `xml:"Name"`
	Age     int      `xml:"Age"`
}

const filePath = "output.xml" // 書き込み先のXMLファイルパス

func main() {
	// 書き込み可能な状態でXMLファイルをオープン(存在しなければ作成、存在すれば上書き)
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	user := User{
		Name: "John",
		Age:  30,
	}

	encoder := xml.NewEncoder(file)
	encoder.Indent("", "    ")
	if err := encoder.Encode(user); err != nil {
		log.Fatal(err)
	}
}

まとめ

今回の記事では、Go言語を用いた各種ファイルフォーマットの読み込みと書き込みのサンプルコードを紹介しました。JSON、YAML、CSV、TXT、EXCEL、INI、XMLと多岐にわたるファイル形式に対応するコード例は、現場で頻繁にファイル操作を行う私自身の経験に基づいており、実務ですぐに活用できる内容となっています。各サンプルコードは公式パッケージの仕様に準拠しているため、初学者から実務者まで参考にしていただければ幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?