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?

K29:【鍛錬】慣れで選ぶと地雷もセット ― CSV/TSV/JSON/XML/INI/YAMLの使い分け

Posted at

連載Index(読む順・公開済(リンク)はここが最新): S00_門前の誓い_総合Index

テキストフォーマットを選ぶ時
「設定ファイルどうする?」「この一覧、Excelに渡せる?」「ファイル連携、相手は何が読める?」みたいに考えてはみるものの、そのとき判断してしまう基準は、結局これだ。

  • 今まで扱ったことがある形式
  • チームが慣れている形式
  • 既存の資産がある形式

それ自体は自然。
ただ、そこで勢いで決めると、データの「形」だけじゃなく運用の「地雷」まで一緒に採用することになるのでよく検討しよう。

  • CSV/TSV:区切り・改行・ダブルクォート・Excel。
  • JSON:差分の読みづらさ・コメント不可・整形と順序の揺れ。
  • YAML:インデント・型推論・実装差。
  • INI:階層と配列の限界。
  • XML:名前空間と冗長さ。

このページは、用途(初期値/設定/永続化/通信/表連携)と運用環境(誰が触るか)から、形式を選ぶための整理。
「互換性(バージョン/安全性)をどう作るか」はK30に記載。


1. ゴール

  • CSV/TSV/JSON/XML/INI/YAMLを「用途(何のデータか)」と「運用環境(誰が触るか)」で選べるようになる
  • 選定理由を言語化し、レビューでブレない基準に落とす
  • 形式ごとの運用地雷(文字コード、改行、Excel、手編集、差分)を先に潰す

2. まず「用途」を言葉にする(ここが曖昧だと毎回揉める)

ここでいう用途は「表か構造か」より前の話。システムの中で何を扱うか。

  • システムの初期値(デフォルト値、初回起動時のテンプレ)
  • 設定ファイル(運用者が変える、環境で変わる、端末で変わる)
  • 永続化(アプリ状態の保存、キャッシュ、オフライン用のローカル保存)
  • データ通信(外部API、他システム連携、ファイル連携、バッチ受け渡し)
  • 出力/受け渡し(Excelに渡す、監査/証跡として残す、ログに近い退避)

同じシステムでも用途は分かれる。ここを分けて考えると、選定が一気に楽になる。

2-1. 用途別の第一候補(最短の当て)

用途(システム内の役割) ありがちな第一候補 その理由 先に決めるべきこと
初期値(テンプレ/デフォルト) JSON / YAML 構造を素直に持てる 整形固定、コメント要否、差分の読みやすさ
運用設定(人が手で触る) INI(浅い) / YAML(構造) 手編集・差分が強い 記法制限、型推論回避、重複キー方針
永続化(アプリ状態/キャッシュ) JSON 実装が素直、取り回しが良い 整形・分割・エラー時の切り分け
データ通信(内部/外部API) JSON / XML(相手都合) 現実的にJSONが多い。相手がXML前提なら合わせる 契約(互換性)はK30、エラーの観測性
ファイル連携(表データ) CSV / TSV 表として受け渡しやすい 引用規約、Excel地雷、文字コード/改行
Excelに渡す/部門連携 CSV / TSV 受け手がExcel中心 Excel地雷(先頭0、日付化、指数表記)

3. 「統一したい」も現実的。その時の考え方

同じシステムなら「1フォーマットに統一した方がやりやすい」という考え方は、実務では強い。
ただし統一の目的と例外の条件を決めないと、統一が負債になる。

3-1. 統一のメリット(現場で効く)

  • 実装とライブラリが一本化される(読み書き、検証、ログ、例外処理)
  • 教育コストが下がる(新メンバーが迷わない)
  • 運用手順が揃う(配置場所、更新手順、差分レビュー)

3-2. 統一の落とし穴(よくある失敗)

  • Excelに渡すのにJSON統一して、結局CSV変換が散らばる
  • 表データまでJSON統一して、現場の目視/集計が辛くなる
  • 設定を全部CSV/INIで統一して、階層や配列が来た瞬間に破綻する
  • 外部連携まで統一しようとして、相手仕様に負ける(結局例外だらけ)

3-3. 実務での落としどころ(「基本 + 例外」を明文化)

  • 基本フォーマットを1つ決める(例: JSON)
  • 例外を用途で固定する(例: Excel連携はCSV、CI/CDはYAML、外部仕様がXMLならXML)
  • 例外は担当者の好みで増やさない(増やすなら用途が増えた証拠として扱う)

例:

  • 内部の永続化/設定: JSON
  • Excelに渡す表データ: CSV/TSV
  • CI/CD設定: YAML(ツール前提)
  • 外部仕様がXML: XML(相手都合)

4. 運用環境の影響(用途とセットで見る)

用途が決まっても、運用環境で向き不向きが変わる。ここを無視すると「設計は正しいのに運用で死ぬ」。

運用環境(誰が触る/どこで使う) 強くなる候補 なぜ効くか ありがちな事故
Excelで開く/業務部門に渡す CSV/TSV 受け手がExcel中心 先頭0消失、日付化、指数表記、文字化け
Gitでレビューする(差分が命) CSV(行が安定)/INI/YAML/整形JSON 目視差分が運用コスト JSON順序揺れ、minifyで差分死亡、CSV複数行レコードで崩壊
人が手で編集する INI(浅い)/YAML(構造)/整形JSON 手編集耐性が重要 YAMLインデント事故、JSONにコメント入れて壊す
外部仕様が決まっている XML/CSV 合わせるしかない XML名前空間、CSV引用規約不一致
CI/CDやIaCの設定 YAML 周辺ツールがYAML前提 型推論、インデント、実装差

5. 最短の決め方(用途→環境→形式)

5-1. 5問で決める

  1. 用途は何か(初期値/設定/永続化/通信/Excel受け渡し)
  • Excelに渡す/表連携 -> CSV/TSV
  • 外部仕様が固定 -> 相手仕様に合わせる(XML/CSVなど)
  • それ以外 -> 2へ
  1. データは表か
  • Yes -> CSV/TSV
  • No -> 3へ
  1. 人が手で編集するか
  • Yes(浅いKey-Value) -> INI
  • Yes(階層/配列が必要) -> YAML/JSON
  • No -> 4へ
  1. 周辺ツールの前提があるか(CI/CDがYAML等)
  • Yes -> 前提に合わせる
  • No -> 5へ
  1. 1フォーマット統一をやるか
  • Yes -> JSONを基本にして例外を用途で固定
  • No -> JSON/YAML/XMLを用途・環境で使い分け

5-2. 選定フロー図


6. フォーマットの最小例(形を先に掴む)

同じ内容を各形式にするとこうなる。

6-1. CSV(表)

Id,Name,Note
1,Alice,OK
2,Bob,"改行を含むメモ
カンマ,や""引用符""も混ざる"

6-2. TSV(表)

Id	Name	Note
1	Alice	OK
2	Bob	"改行を含むメモ
タブ	や""引用符""も混ざる"

6-3. JSON(構造)

{
  "id": 1,
  "name": "Alice",
  "note": "OK"
}

6-4. YAML(構造、手編集寄り)

id: 1
name: Alice
note: "OK"

6-5. XML(外部仕様で見ることが多い)

<Person>
  <Id>1</Id>
  <Name>Alice</Name>
  <Note>OK</Note>
</Person>

6-6. INI(浅い設定)

[Person]
Id=1
Name=Alice
Note=OK

7. 形式別: 使いどころと運用地雷(用途の例つき)

ここで扱うのは「選定」と「運用地雷」。
互換性・バージョン・安全なデシリアライズ設計はK30に寄せる。


7-1. CSV(表の王道)

使いどころ(用途レベル)

  • 表データの受け渡し(ファイル連携、バッチ)
  • Excelに渡す一覧データ
  • 監査用に「表として残す」退避

記述例(用途のイメージ)

  • 表連携(エクスポート/インポート)
    例: 取引一覧、エラー一覧、棚卸結果、集計結果、マスタ差分
ItemCode,Qty,Price,Note
00123,10,1200,"備考にカンマ,が混ざる"
00456,1,980,"改行が混ざると
1行=1レコードが崩れる"

運用地雷(具体)

  • 引用規約(区切り/改行/ダブルクォート)を舐めると壊れる
    Split(',') で読めるのは「たまたま壊れてないだけ」になりやすい。
  • 改行を含むセルが来た瞬間、1行=1レコードが崩れる
    レコードが複数行になり、差分レビュー、grep、行番号での切り分けが難しくなる。
  • ダブルクォートのエスケープで見づらくなる
    テキストが長い、カンマが多い、改行が多いほど "...""" が増え、内容が追いにくい。
  • Excelの勝手変換(先頭0、日付化、指数表記、桁落ち)
  • 文字コード(BOMあり/なし)で文字化け

7-2. TSV(CSVのカンマ地雷を避ける)

使いどころ(用途レベル)

  • 表連携だが、カンマが頻出する説明文を含む
  • コピペや目視が多い表データ(ただしタブ混入が少ない前提)

記述例(用途のイメージ)

  • 表連携(文章列が重い)
    例: 問い合わせ内容、説明、ログ断片を含む一覧
Id	Title	Detail
1	障害	"カンマ,が多い文章でも列崩れしにくい"
2	調査	"タブ	が混ざると列が崩れる"

運用地雷(具体)

  • タブ混入で列が崩れる(見た目で気づきにくい)
  • 改行を含むセルは結局引用が必要で、見づらさは残る
  • Excel連携ならExcel地雷は避けられない

7-3. JSON(構造化は得意。運用は差分とコメントで詰む)

使いどころ(用途レベル)

  • 初期値テンプレ(構造がある)
  • 設定ファイル(ただし「人が手で触る」なら差分運用を先に決める)
  • 永続化(アプリ状態/キャッシュ)
  • データ通信(外部APIで多い)

記述例(用途のイメージ)

  • 初期値テンプレ/設定ファイル(アプリ設定)
    例: URL一覧、タイムアウト、機能フラグ、画面レイアウト
{
  "features": { "isEnabled": true, "timeoutMs": 3000 },
  "endpoints": [
    { "name": "primary", "url": "https://api.example.com" }
  ]
}
  • 永続化(キャッシュ/状態保存)
    例: 最終ログイン、最近使ったファイル、検索履歴
{ "lastLoginUtc": "2026-01-18T06:00:00Z", "recentFiles": ["a.txt","b.txt"] }

運用地雷(具体)

  • コメントが書けない
    設定に「なぜこの値か」を書きたくなるが、JSONは仕様上コメントが無い。
    その結果、///* */ を入れて壊す、別の場所にメモが散って迷子になる、が起きる。
  • 整形が揺れると差分が読めない
    minify(1行)にすると、パースエラーが「列 15342」になり切り分け不能になる。
    整形しても、出力ツールが変わるとインデント/改行が揺れて差分がノイズになる。
  • 順序が揺れるとレビューが止まる
    JSONのプロパティ順は本質ではないが、Git差分では順序が重要になる。
    自動整形やシリアライザが順序を変えると、実質変更が埋もれる。
  • 階層が深い/巨大ファイルだと追いにくい
    波括弧と角括弧が続き、エラー位置がどのブロックか追いにくい。
    配列の中に同型オブジェクトが続くと、どの要素が壊れているかも目視で追いづらい。
  • マージコンフリクトが起きやすい
    1つの大きいJSONを複数人で触ると、同じ行付近で衝突しやすい。

7-4. YAML(手編集に強いが、インデントと型推論が敵)

使いどころ(用途レベル)

  • CI/CDなどツール設定(前提としてYAMLが多い)
  • 運用設定で「コメントが必要」「手編集が中心」

記述例(用途のイメージ)

  • CI/CDやデプロイ設定
    例: ジョブ、環境変数、実行条件、手順
jobs:
  build:
    steps:
      - run: dotnet test
# 理由や注意点をコメントで残せる
  • 運用設定(人が手で編集する構造)
    例: 環境ごとのエンドポイント、機能の有効化
features:
  isEnabled: true
endpoints:
  - name: primary
    url: https://api.example.com

運用地雷(具体)

  • インデントが意味を持つ(見た目のズレが意味のズレ)
  • 型推論で意図しない型になる(yes/no、001、日付っぽい値など)
  • 実装差で挙動が割れる(同じYAMLでもツールにより解釈差が出る)

7-5. XML(外部仕様が強い連携に寄せる)

使いどころ(用途レベル)

  • 外部仕様でXML指定
  • 既存資産やスキーマ(XSD)前提の連携
  • 厳密な検証が必要で、周辺ツールもXML前提

記述例(用途のイメージ)

  • 外部連携(相手仕様がXML)
    例: 既存の基幹、業界標準、スキーマ付きファイル連携
<Request xmlns="urn:example:v1">
  <Header>
    <RequestId>abc-123</RequestId>
  </Header>
  <Body>
    <Amount>1200</Amount>
  </Body>
</Request>

運用地雷(具体)

  • 名前空間で転ぶ(同じ要素名でも別扱いになり、合わないと読めない)
  • 冗長で手編集が辛い(差分もノイズが増えやすい)
  • 整形方針が揺れると差分がノイズになる

7-6. INI(端末別の小さい上書きだけに使う)

使いどころ(用途レベル)

  • 端末ローカルの設定(WinFormsの個人差分など)
  • 小さい運用設定(画面分程度)を手で直す

記述例(用途のイメージ)

  • 端末別の上書き(軽い設定)
    例: 画面サイズ、ログレベル、接続先の切替(ローカルだけ)
[App]
Theme=Dark
LogLevel=Info
TimeoutMs=3000

[Window]
Width=1280
Height=720

運用地雷(分かりやすく言うと)

  • 「階層」や「配列」が来た瞬間に終わる
    INIは基本的に「キー=値」。構造を持たせると無理やりになって破綻する。
  • 重複キーの解釈が揺れる
    Key=... が2回出たときに「後勝ち/先勝ち/エラー」が実装で変わる。

8. 地雷マップ

8-0. 全体像

8-1. TOOL: Excel/周辺ツール起因

8-2. PARSE: パース/構文起因

8-3. DIFF: 差分/レビュー起因

8-4. EDIT: 手編集/運用起因

8-5. INTEROP: 外部連携/相手仕様起因


9. 形式より先に固定すべき運用仕様

形式を決めても、運用仕様が決まっていないと不具合になる。最低限ここは決める。

  • 文字コード: UTF-8固定が基本(BOMの有無も決める)
  • 改行: LF/CRLFを固定(Excelや社内ツール都合があるなら先に決める)
  • 更新方式: 原子的更新(テンポラリ -> 置換)を標準にする
  • 入力検証: 壊れたデータを握り潰さず、どこで壊れたかを出す
  • 失敗時のログ: ファイルパス、行番号(またはキー名/JSONパス)、例外を残す
  • サンプル: 正常サンプルをリポジトリに置く(実運用の基準になる)

10. 実装の最小セット(選定後の最低ライン)

10-1. 原子的更新(テンポラリを書いてから差し替える)

using System.Text;

public static class AtomicFile
{
    public static void WriteAllTextAtomic(string path, string content, Encoding encoding)
    {
        var dir = Path.GetDirectoryName(path) ?? ".";
        Directory.CreateDirectory(dir);

        var tmp = path + ".tmp";
        File.WriteAllText(tmp, content, encoding);

        if (File.Exists(path))
        {
            var bak = path + ".bak";
            File.Replace(tmp, path, bak, ignoreMetadataErrors: true);
        }
        else
        {
            File.Move(tmp, path);
        }
    }
}

10-2. JSON(.NET 8) 整形を固定する

using System.Text.Json;

public static class JsonText
{
    private static readonly JsonSerializerOptions Options = new()
    {
        WriteIndented = true,
        PropertyNameCaseInsensitive = true
    };

    public static string Serialize<T>(T value) => JsonSerializer.Serialize(value, Options);

    public static T? Deserialize<T>(string json) => JsonSerializer.Deserialize<T>(json, Options);
}

10-3. CSV/TSVは手実装しない(方針にする)

CSV/TSVは引用規約が本体。Split(',')Split('\t') は「壊れたら終わる」実装になりやすい。
方針として「実装はライブラリに任せる」を決めると事故が減る。

  • 例: CsvHelper など(区切り文字を変えればCSV/TSV両対応がしやすい)

10-4. YAMLは記法と型推論を縛る

  • 高度機能(アンカー、マージ)は原則禁止
  • 型推論で不具合になる値はクォートする(yes/no、001、日付っぽい値など)
  • 整形(インデント幅)を統一する

11. チートシート(用途で引く)

  • 初期値テンプレ: JSON / YAML(コメントが要るならYAML、差分運用できるなら整形JSON)
  • 設定ファイル(運用者が触る): INI(浅い) / YAML(構造) / 整形JSON(差分運用を決めた場合)
  • 永続化(アプリ状態/キャッシュ): JSON
  • データ通信(外部API): JSON(相手都合でXMLもあり)
  • ファイル連携(表データ): CSV/TSV
  • Excelに渡す: CSV/TSV(Excel地雷を仕様に入れる)
  • 形式統一をやる: JSONを基本にして、例外を用途で固定する

関連トピック


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?