C Sharpの基礎 - TOML

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

TOML (Tom's Obvious, Minimal Language) は人間や機械にとって読みやすく、解析しやすい設定ファイル形式である。
TOMLファイルは、設定ファイルやデータ保存の効率的な方法として注目されている。

TOMLファイルの特徴として、JSON形式よりも人間が読みやすい点が挙げられる。
また、XMLと比べてシンプルな構造を持ちながら、十分な表現力を備えている。

TOMLファイルの構造は、キーと値のペアを基本としており、セクションを使用して階層構造を表現することもできる。
これにより、複雑な設定やデータ構造を直感的に表現することができる。

C#でTOMLファイルを使用する場合は、一般的に、サードパーティ製ライブラリを使用する。
以下に示すライブラリを使用することにより、TOMLファイルの読み書きを簡単に行うことができる。


C#でTOMLファイルを読み込む場合は、ファイルを開いて内容を解析して、その結果をオブジェクトとして扱う。
逆に、C#のオブジェクトをTOML形式で書き込むこともできる。

C#プロジェクトでTOMLファイルを使用するメリットを以下に示す。

  • 設定ファイルの管理が容易になる。
  • データの構造化が簡単である。
  • 他の言語やプラットフォームとの互換性が高い。


ただし、TOMLファイルはまだJSONファイルほど広く採用されているわけではないため、チーム内での合意やプロジェクトの要件に合わせて採用を検討する必要がある。

TOMLファイルの処理を効率的に行うためには、適切なライブラリの選択とTOML形式の特性を理解することが重要である。

TOMLの採用を検討することにより、より効率的な設定管理やデータ処理が可能になる。


TOMLの構文

TOMLファイルの主な構文要素を以下に示す。

  • キーと値のペア
    基本的な形式は、<キー名> = <値> である。
    例: name = "TOML Example"

  • 文字列
    • 基本文字列
      ダブルクォートで囲む
      "Hello"
    • リテラル文字列
      シングルクォートで囲む
      'C:\Users\username'

  • 数値
    • 整数
      42
    • 浮動小数点
      3.14

  • ブーリアン
    true または false

  • 日付と時刻
    ISO 8601形式を使用する。
    例: date = 2023-03-27T15:32:00Z

  • 配列
    角括弧で囲む。
    例: colors = [ "red", "yellow", "green" ]

  • テーブル (セクション)
    角括弧で囲んだ名前で定義する。
    例:
       [database]
       server = "192.168.1.1"
       ports = [ 8001, 8001, 8002 ]
    

  • インラインテーブル
    中括弧で囲む。
    例: point = { x = 1, y = 2 }

  • テーブルの配列
    2重の角括弧で定義する。
    例:
       [[fruits]]
       name = "apple"
    
       [[fruits]]
       name = "banana"
    

  • コメント
    シャープ記号 (#) を使用する。



TOMLファイルの例

 # config.tomlファイル
 
 title = "設定ファイル"  # トップレベルのキー
 
 [user]                # ユーザ情報のセクション
 name = "山田太郎"
 age = 30
 email = "yamada@example.com"
 
 [application]         # アプリケーション設定のセクション
 version = "1.0.0"
 debug_mode = false
 
 [database]            # データベース接続情報のセクション
 host = "localhost"
 port = 5432
 username = "admin"
 password = "secret"
 
 [features]            # 機能のオン / オフを制御するセクション
 enabled = ["login", "logout", "dashboard"]
 disabled = ["admin_panel"]
 
 [logging]             # ロギング設定のセクション
 level = "info"
 file = "/var/log/app.log"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.1"
 role = "frontend"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.2"
 role = "backend"



TOMLファイルとYAMLファイルの比較

TOMLファイルは、YAMLファイルより学習が容易な傾向がある。
一般的に、TOMLファイルの方がYAMLファイルよりパースが高速である。

YAMLの特徴

  • 人間が読みやすい。
  • 階層構造を表現しやすい。
  • 多くの言語やフレームワークでサポートされている。
  • 複雑なデータ構造を表現できる。
  • 複数のドキュメントを1つのファイルに含められる。
  • アンカーとエイリアスを使用して、データの再利用が可能。
  • フロースタイルと折りたたみスタイルの2つの記述スタイルがある。
  • JSONのスーパーセットであり、JSONと互換性がある。
  • YAMLファイルは、大規模で複雑な設定に適している。
  • YAMLの方が長く存在しており、より広くサポートされている。


TOMLの特徴

  • シンプルで明確な構文である。
  • 日付や時刻のデータ型をネイティブにサポートされている。
  • 曖昧さが少ない。
  • コメントが記述しやすい。
  • INIファイルに似た構造で、慣れ親しみやすい。
  • 配列の配列や複雑な入れ子構造をサポートしている。
  • キーにドット記法を使用できる
    これは、セクション内のサブセクションを表現しやすい。
  • 型推論が強く、明示的な型宣言が少なくて済む。
  • TOMLは小〜中規模の設定ファイルに適している。



Tomlynライブラリ

Tomlynライブラリとは

Tomlynライブラリは、C#でTOML (Tom's Obvious, Minimal Language) ファイルを扱うためのライブラリである。
TOMLは設定ファイルフォーマットとして人気があり、読みやすさと書きやすさを兼ね備えている。

Tomlynライブラリの主な特徴として、TOMLファイルの解析と生成が挙げられる。
このライブラリを使用することにより、開発者はTOMLデータを簡単にC#オブジェクトに変換したり、C#オブジェクトからTOMLデータを生成することができる。

パフォーマンスもTomlynライブラリの強みの1つである。
効率的な解析アルゴリズムを採用しており、大きなTOMLファイルでも高速に処理することができる。
また、メモリ使用量も抑えられるよう設計されている。

柔軟性もTomlynライブラリの特徴である。
様々なTOMLデータ型 (文字列、整数、浮動小数点数、ブール値、日時、配列、テーブル等) をサポートしており、複雑な構造のTOMLファイルも扱える。

エラーハンドリングにも配慮がなされており、解析中に問題が発生した場合は、詳細なエラーメッセージと行番号情報を提供して、デバッグを容易にする。

さらに、Tomlynライブラリは.NET Standardに準拠しているため、様々な.NETプラットフォーム (.NET Framework、.NET Core、Xamarin等) で使用できる。

使いやすさも重視されており、直感的なAPIを提供しており、基本的な操作は数行のコードで実装でき、複雑な操作も比較的簡単に行えるよう設計されている。

これらの特徴により、Tomlynライブラリは設定ファイルの管理やTOMLフォーマットを使用するアプリケーションの開発において、非常に有用なツールとなっている。

Tomlynライブラリのライセンスは、2条項BSDライセンスに準拠している。


Tomlynライブラリのインストール

RiderまたはVisual StudioからNuGetを使用して、Tomlynライブラリをインストールする。

  • Riderの場合
    1. プロジェクトを開く。
    2. [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
    3. メイン画面下部にある[パッケージ]タブから Tomlyn と入力して検索する。
    4. メイン画面下部の右にある[+]ボタンを押下して、Tomlynライブラリをインストールする。

  • Visual Studioの場合
    1. プロジェクトを開く。
    2. NuGetパッケージマネージャーを開く。
      • [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
      • または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
    3. Tomlynライブラリを検索する。
      NuGetパッケージマネージャーの検索ボックスに Tomlyn と入力して検索する。
    4. Tomlynライブラリのインストール
      検索結果からTomlynライブラリを選択して、[インストール]ボタンを押下する。
    5. インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
    6. 参照の確認
      インストールが完了した後、プロジェクトの参照にTomlynライブラリが追加されていることを確認する。

  • パッケージマネージャーコンソールからインストールする場合
    1. プロジェクトを開く。
    2. [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
    3. パッケージマネージャーコンソールから、Tomlynライブラリをダウンロードしてインストールする。
      Install-Package Tomlyn
    4. ソリューションエクスプローラーのプロジェクトの参照において、Tomlynライブラリが追加されていることを確認する。

  • dotnetコマンドを使用する場合
    1. ターミナルを開く。
    2. プロジェクトのルートディレクトリに移動する。
    3. Tomlynライブラリをインストールする。
      最新の安定版をインストールする場合
      dotnet add package Tomlyn

      バージョンを指定してインストールする場合
      dotnet add package Tomlyn --version <バージョン>

    ※注意
    プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。
    プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。


プロジェクトにおいて、Tomlynライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。
これにより、名前空間を使用することで、TOMLのシリアライズ / デシリアライズに関する主要な機能にアクセスすることができる。

 using Tomlyn;
 using Tomlyn.Model;


また、大きなサイズなTOMLファイルを扱う場合は、ストリーミング処理を使用することを推奨する。

TOMLファイルの読み込み

以下の例では、Tomlynライブラリを使用して、指定されたTOMLファイルを読み込み・解析して、その内容を表示している。

  • ファイルの読み込みと設定の表示
    ReadTomlConfigAsyncとDisplayConfigAsyncメソッドで行う。
  • ストリーミング処理
    ReadTomlConfigAsyncメソッド内でFileStreamを使用して、大きなファイルでも効率的に読み込めるようにしている。
    useAsyncプロパティをtrueを指定することにより、非同期I/O操作を有効にしている。
  • TOMLファイルの解析
    Toml.ToModelメソッドを使用して、TOMLの内容をTomlTableオブジェクトに変換している。
  • 設定の表示
    DisplayConfigAsyncメソッド内で、解析されたTOML設定の各セクションを順番に表示している。
    ネストされた構造や配列も適切に処理している。


 # 使用するTOMLファイル
 
 title = "設定ファイル"  # トップレベルのキー
 
 [user]                # ユーザ情報のセクション
 name = "山田太郎"
 age = 30
 email = "yamada@example.com"
 
 [application]         # アプリケーション設定のセクション
 version = "1.0.0"
 debug_mode = false
 
 [database]            # データベース接続情報のセクション
 host = "localhost"
 port = 5432
 username = "admin"
 password = "secret"
 
 [features]            # 機能のオン / オフを制御するセクション
 enabled = ["login", "logout", "dashboard"]
 disabled = ["admin_panel"]
 
 [logging]             # ロギング設定のセクション
 level = "info"
 file = "/var/log/app.log"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.1"
 role = "frontend"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.2"
 role = "backend"


 using System;
 using System.IO;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using Tomlyn;
 using Tomlyn.Model;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "sample.toml";  // TOMLファイルのパス
 
       try
       {
          // ファイルを非同期で読み込み・解析
          var config = await ReadTomlConfigAsync(filePath);
 
          // 解析した設定を表示
          await DisplayConfigAsync(config);
       }
       catch (Exception ex)
       {
          Console.WriteLine($"エラーが発生: {ex.Message}");
       }
    }
 
    // TOMLファイルを非同期で読み込み・解析
    static async Task<TomlTable> ReadTomlConfigAsync(string filePath)
    {
       using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true))
       using (var reader = new StreamReader(stream))
       {
          string tomlContent = await reader.ReadToEndAsync();
          return Toml.ToModel(tomlContent);
       }
    }
 
    // 解析された設定を非同期で表示
    static async Task DisplayConfigAsync(TomlTable config)
    {
       await Task.Run(() =>
       {
          Console.WriteLine($"タイトル: {config["title"]}");
 
          // ユーザ情報の表示
          var user = (TomlTable)config["user"];
          Console.WriteLine("ユーザ情報:");
          Console.WriteLine($"名前: {user["name"]}");
          Console.WriteLine($"年齢: {user["age"]}");
          Console.WriteLine($"メール: {user["email"]}");
 
          // アプリケーション設定の表示
          var app = (TomlTable)config["application"];
          Console.WriteLine("アプリケーション設定:");
          Console.WriteLine($"バージョン: {app["version"]}");
          Console.WriteLine($"デバッグモード: {app["debug_mode"]}");
 
          // データベース接続情報の表示
          var db = (TomlTable)config["database"];
          Console.WriteLine("データベース接続情報:");
          Console.WriteLine($"ホスト: {db["host"]}");
          Console.WriteLine($"ポート: {db["port"]}");
          Console.WriteLine($"ユーザー名: {db["username"]}");
          Console.WriteLine($"パスワード: {db["password"]}");
 
          // 機能の表示
          var features = (TomlTable)config["features"];
          Console.WriteLine("機能:");
          Console.WriteLine($"有効: {string.Join(", ", (List<object>)features["enabled"])}");
          Console.WriteLine($"無効: {string.Join(", ", (List<object>)features["disabled"])}");
 
          // ロギング設定の表示
          var logging = (TomlTable)config["logging"];
          Console.WriteLine("ロギング設定:");
          Console.WriteLine($"レベル: {logging["level"]}");
          Console.WriteLine($"ファイル: {logging["file"]}");
 
          // サーバ情報の表示
          var servers = (List<object>)config["servers"];
          Console.WriteLine("サーバ情報:");
          foreach (TomlTable server in servers)
          {
             Console.WriteLine($"IP: {server["ip"]}");
             Console.WriteLine($"役割: {server["role"]}");
             Console.WriteLine();
          }
       });
    }
 }


TOMLファイルの書き込み

以下の例では、Tomlynライブラリを使用して、指定されたTOMLファイルを生成している。

  • ストリーミング処理
    WriteTomlConfigAsyncメソッド内でFileStreamを使用して、効率的に書き込んでいる。
    また、useAsyncプロパティにtrueを指定することにより、非同期I/O操作を有効にしている。
  • TOMLファイルの生成
    CreateTomlConfigメソッドで、指定された構造のTOML設定をTomlTableオブジェクトとして作成している。
    Toml.FromModelメソッドを使用して、TomlTableオブジェクトをTOML文字列に変換している。
  • ファイルへの書き込み
    WriteTomlConfigAsyncメソッド内で、生成されたTOML文字列をファイルに非同期で書き込んでいる。


 using System;
 using System.IO;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using Tomlyn;
 using Tomlyn.Model;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "config.toml";  // 書き込むTOMLファイルのパス
 
       try
       {
          // TOML設定を作成
          var config = CreateTomlConfig();
 
          // 設定をTOMLファイルに非同期で書き込み
          await WriteTomlConfigAsync(config, filePath);
       }
       catch (Exception ex)
       {
          Console.WriteLine($"エラーが発生: {ex.Message}");
       }
    }
 
    // TOML設定を作成
    static TomlTable CreateTomlConfig()
    {
       var config = new TomlTable
       {
          ["title"] = "設定ファイル",
          ["user"] = new TomlTable
          {
             ["name"] = "山田太郎",
             ["age"] = 30,
             ["email"] = "yamada@example.com"
          },
          ["application"] = new TomlTable
          {
             ["version"] = "1.0.0",
             ["debug_mode"] = false
          },
          ["database"] = new TomlTable
          {
             ["host"] = "localhost",
             ["port"] = 5432,
             ["username"] = "admin",
             ["password"] = "secret"
          },
          ["features"] = new TomlTable
          {
             ["enabled"] = new List<string> { "login", "logout", "dashboard" },
             ["disabled"] = new List<string> { "admin_panel" }
          },
          ["logging"] = new TomlTable
          {
             ["level"] = "info",
             ["file"] = "/var/log/app.log"
          },
          ["servers"] = new List<TomlTable>
          {
             new TomlTable { ["ip"] = "192.168.1.1", ["role"] = "frontend" },
             new TomlTable { ["ip"] = "192.168.1.2", ["role"] = "backend" }
          }
       };
 
       return config;
    }
 
    // TOML設定をファイルに非同期で書き込む
    static async Task WriteTomlConfigAsync(TomlTable config, string filePath)
    {
       // TomlTableをTOML文字列に変換
       string tomlString = Toml.FromModel(config);
 
       // ファイルを非同期で書き込む
       using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
       using (var writer = new StreamWriter(stream))
       {
          await writer.WriteAsync(tomlString);
       }
    }
 }


TOMLファイルの修正

以下の例では、Tomlynライブラリを使用して、以下に示すTOMLファイルの値を修正している。

  • ストリーミング処理
    ReadTomlConfigAsyncおよびWriteTomlConfigAsyncメソッド内でFileStreamを使用して、効率的に読み書きしている。
    また、useAsyncプロパティの値をtrueを指定することにより、非同期I/O操作を有効にしている。
  • TOMLファイルの更新
    UpdateConfigメソッドで、指定された変更を行っている。
    • [application]セクション -> "version"キーの値を"1.1.0"に変更する。
    • [logging]セクション -> "level"キーそのものを削除する。
    • [features]セクション -> "enabled"キーの配列から"logout"を削除する。
    • 2つ目の[[servers]]配列 -> "ip"キーの値を"192.168.1.10"に変更する。
  • ファイルへの書き込み
    WriteTomlConfigAsyncメソッド内で、更新されたTOMLデータをファイルに非同期で書き込んでいる。


 using System;
 using System.IO;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using Tomlyn;
 using Tomlyn.Model;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "config.toml";  // 修正するTOMLファイルのパス
 
       try
       {
          // TOMLファイルを非同期で読み込み・解析
          var config = await ReadTomlConfigAsync(filePath);
 
          // ファイルを修正
          UpdateConfig(config);
 
          // 修正したデータをTOMLファイルに非同期で書き込む
          await WriteTomlConfigAsync(config, filePath);
       }
       catch (FileNotFoundException)
       {
          Console.WriteLine($"エラー: ファイル '{filePath}' が存在しない");
       }
       catch (UnauthorizedAccessException)
       {
          Console.WriteLine($"エラー: ファイル '{filePath}' にアクセスする権限がない");
       }
       catch (TomlParseException ex)
       {
          Console.WriteLine($"エラー: TOMLファイルの解析に失敗: {ex.Message}");
       }
       catch (Exception ex)
       {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
       }
    }
 
    // TOMLファイルを非同期で読み込む
    static async Task<TomlTable> ReadTomlConfigAsync(string filePath)
    {
       using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true))
       using (var reader = new StreamReader(stream))
       {
          string tomlContent = await reader.ReadToEndAsync();
          return Toml.ToModel(tomlContent);
       }
    }
 
    // データを修正する
    static void UpdateConfig(TomlTable config)
    {
       // [application]セクション -> "version"キーを"1.1.0"に変更
       ((TomlTable)config["application"])["version"] = "1.1.0";
 
       // [features]セクション -> "enabled"キー (配列) から"logout"を削除
       var enabledFeatures = (List<object>)((TomlTable)config["features"])["enabled"];
       enabledFeatures.Remove("logout");
 
       // 2つ目の[[servers]]配列 -> "ip"セクションを"192.168.1.10"に変更
       var servers = (List<object>)config["servers"];
       if (servers.Count >= 2)
       {
          ((TomlTable)servers[1])["ip"] = "192.168.1.10";
       }
 
       // [logging]セクション -> "level"キーを削除
       ((TomlTable)config["logging"]).Remove("level");
    }
 
    // 更新された設定をTOMLファイルに非同期で書き込む
    static async Task WriteTomlConfigAsync(TomlTable config, string filePath)
    {
       string tomlString = Toml.FromModel(config);
 
       using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
       using (var writer = new StreamWriter(stream))
       {
          await writer.WriteAsync(tomlString);
       }
    }
 }



Tommyライブラリ

Tommyライブラリとは

Tommyライブラリは、C#で開発された軽量かつ高速なメモリ内データ構造ライブラリである。
主な特徴として、ハッシュテーブルと順序付き辞書の実装に焦点を当てている。

このライブラリの中核となるのは、Tommy.Tommyという汎用的なハッシュテーブル実装である。
これは、高速な検索、挿入、削除操作を提供しており、同時にメモリ使用量を最小限に抑えるように設計されている。

Tommyライブラリは、大量のデータを扱う必要があるアプリケーションやパフォーマンスが重要な場面で特に有効である。
例えば、ゲーム開発、リアルタイムシステム、大規模データ処理等の分野で活用されることがある。

このライブラリの特筆すべき点として、カスタマイズ性の高さが挙げられる。
開発者は自身のニーズに合わせて、ハッシュ関数やメモリ割り当て戦略をカスタマイズすることができる。
これにより、特定のユースケースに対して最適化された実装が可能となる。

また、Tommyライブラリは.NET Standard 2.0をサポートしているため、幅広い.NETプラットフォームで使用することができる。
これには、.NET Framework、.NET Core、Xamarinなどが含まれる。

基本的な操作は他の一般的なコレクションタイプと似ているが、より高度な機能や最適化オプションも提供されている。

ただし、Tommyライブラリを使用する際は、その特性や制限を十分に理解することが重要である。
例えば、一般的なコレクションタイプと比較して、メモリ使用量やパフォーマンスの特性が異なる場合がある。
そのため、プロジェクトの要件に適しているかどうかを慎重に評価する必要がある。

Tommyライブラリのライセンスは、MITライセンスに準拠している。


Tommyライブラリのインストール

RiderまたはVisual StudioからNuGetを使用して、Tommyライブラリをインストールする。

  • Riderの場合
    1. プロジェクトを開く。
    2. [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
    3. メイン画面下部にある[パッケージ]タブから Tommy と入力して検索する。
    4. メイン画面下部の右にある[+]ボタンを押下して、Tommyライブラリをインストールする。

  • Visual Studioの場合
    1. プロジェクトを開く。
    2. NuGetパッケージマネージャーを開く。
      • [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
      • または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
    3. Tommyライブラリを検索する。
      NuGetパッケージマネージャーの検索ボックスに Tommy と入力して検索する。
    4. Tommyライブラリのインストール
      検索結果からTommyライブラリを選択して、[インストール]ボタンを押下する。
    5. インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
    6. 参照の確認
      インストールが完了した後、プロジェクトの参照にTommyライブラリが追加されていることを確認する。

  • パッケージマネージャーコンソールからインストールする場合
    1. プロジェクトを開く。
    2. [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
    3. パッケージマネージャーコンソールから、Tommyライブラリをダウンロードしてインストールする。
      Install-Package Tommy
    4. ソリューションエクスプローラーのプロジェクトの参照において、Tommyライブラリが追加されていることを確認する。

  • dotnetコマンドを使用する場合
    1. ターミナルを開く。
    2. プロジェクトのルートディレクトリに移動する。
    3. Tommyライブラリをインストールする。
      最新の安定版をインストールする場合
      dotnet add package Tommy

      バージョンを指定してインストールする場合
      dotnet add package Tommy --version <バージョン>

    ※注意
    プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。
    プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。


プロジェクトにおいて、Tommyライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。
これにより、名前空間を使用することで、TOMLのシリアライズ / デシリアライズに関する主要な機能にアクセスすることができる。

 using Tommy;


また、大きなサイズなTOMLファイルを扱う場合は、ストリーミング処理を使用することを推奨する。

使用するTOMLファイル

 # 使用するTOMLファイル
 
 title = "設定ファイル"  # トップレベルのキー
 
 [user]                # ユーザ情報のセクション
 name = "山田太郎"
 age = 30
 email = "yamada@example.com"
 
 [application]         # アプリケーション設定のセクション
 version = "1.0.0"
 debug_mode = false
 
 [database]            # データベース接続情報のセクション
 host = "localhost"
 port = 5432
 username = "admin"
 password = "secret"
 
 [features]            # 機能のオン / オフを制御するセクション
 enabled = ["login", "logout", "dashboard"]
 disabled = ["admin_panel"]
 
 [logging]             # ロギング設定のセクション
 level = "info"
 file = "/var/log/app.log"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.1"
 role = "frontend"
 
 [[servers]]           # サーバ情報の配列
 ip = "192.168.1.2"
 role = "backend"


TOMLファイルの読み込み

以下の例では、指定されたTOMLファイルを非同期で読み込み、その内容を解析・表示している。

  • 非同期処理
    ファイルの読み込み・解析では、await TOML.ParseAsync(reader)メソッドを使用する。
  • ストリーミング処理
    StreamReaderクラスを使用して、ファイルをストリームとして読み込む。
  • 構造化されたデータの読み込み
    セクションごとに適切にデータを読み込み・表示している。
    配列データ (例: features、servers) は、繰り返し文を使用して処理する。


 using System;
 using System.IO;
 using System.Threading.Tasks;
 using Tommy;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "sample.toml";  // TOMLファイルのパス
 
       try
       {
          // TOMLファイルを非同期で読み込む
          using (var reader = new StreamReader(filePath))
          {
             var toml = await TOML.ParseAsync(reader);
 
             // トップレベルのキーを読み込む
             Console.WriteLine($"タイトル: {toml["title"]}");
 
             // ユーザ情報のセクションを読み込む
             var user = toml["user"];
             Console.WriteLine($"ユーザ名: {user["name"]}");
             Console.WriteLine($"年齢: {user["age"]}");
             Console.WriteLine($"メール: {user["email"]}");
 
             // アプリケーション設定のセクションを読み込む
             var app = toml["application"];
             Console.WriteLine($"バージョン: {app["version"]}");
             Console.WriteLine($"デバッグモード: {app["debug_mode"]}");
 
             // データベース接続情報のセクションを読み込む
             var db = toml["database"];
             Console.WriteLine($"ホスト: {db["host"]}");
             Console.WriteLine($"ポート: {db["port"]}");
             Console.WriteLine($"ユーザ名: {db["username"]}");
             Console.WriteLine($"パスワード: {db["password"]}");
 
             // 機能のオン / オフを制御するセクションを読み込む
             var features = toml["features"];
             Console.WriteLine("有効な機能:");
             foreach (var feature in features["enabled"].AsArray)
             {
                Console.WriteLine($"- {feature}");
             }
             Console.WriteLine("無効な機能:");
             foreach (var feature in features["disabled"].AsArray)
             {
                Console.WriteLine($"- {feature}");
             }
 
             // ロギング設定のセクションを読み込む
             var logging = toml["logging"];
             Console.WriteLine($"ログレベル: {logging["level"]}");
             Console.WriteLine($"ログファイル: {logging["file"]}");
 
             // サーバ情報の配列を読み込む
             var servers = toml["servers"].AsArray;
             Console.WriteLine("サーバ情報:");
             foreach (var server in servers)
             {
                Console.WriteLine($"IP: {server["ip"]}, 役割: {server["role"]}");
             }
          }
       }
       catch (FileNotFoundException)
       {
          Console.WriteLine($"エラー: ファイル '{filePath}' が存在しない");
       }
       catch (TomlParseException ex)
       {
          Console.WriteLine($"エラー: TOMLファイルの解析に失敗  行 {ex.Line}, 列 {ex.Column}: {ex.Message}");
       }
       catch (Exception ex)
       {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
       }
    }
 }


TOMLファイルの書き込み

以下の例では、指定されたTOMLファイルの構造に従ってデータを作成して、非同期でファイルに書き込んでいる。

  • 非同期処理
    ファイルの書き込みでは、await tomlTable.WriteToAsync(writer)メソッドを使用している。
  • ストリーミング処理
    StreamWriterクラスを使用して、ファイルをストリームとして書き込んでいる。
  • 構造化されたデータの作成
    TomlTableとTomlArrayを使用して、TOMLファイルの構造を再現している。
    セクションごとに適切にデータを構造化している。


 using System;
 using System.IO;
 using System.Threading.Tasks;
 using Tommy;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "sample.toml";  // 書き込むTOMLファイルのパス
 
       try
       {
          // TOMLデータを作成
          var tomlTable = new TomlTable
          {
             // トップレベルのキー
             ["title"] = "設定ファイル",
 
             // ユーザ情報のセクション
             ["user"] = new TomlTable
             {
                ["name"] = "山田太郎",
                ["age"] = 30,
                ["email"] = "yamada@example.com"
             },
 
             // アプリケーション設定のセクション
             ["application"] = new TomlTable
             {
                ["version"] = "1.0.0",
                ["debug_mode"] = false
             },
 
             // データベース接続情報のセクション
             ["database"] = new TomlTable
             {
                ["host"] = "localhost",
                ["port"] = 5432,
                ["username"] = "admin",
                ["password"] = "secret"
             },
 
             // 機能のオン/オフを制御するセクション
             ["features"] = new TomlTable
             {
                ["enabled"] = new TomlArray { "login", "logout", "dashboard" },
                ["disabled"] = new TomlArray { "admin_panel" }
             },
 
             // ロギング設定のセクション
             ["logging"] = new TomlTable
             {
                ["level"] = "info",
                ["file"] = "/var/log/app.log"
             },
 
             // サーバ情報の配列
             ["servers"] = new TomlArray
             {
                new TomlTable
                {
                   ["ip"] = "192.168.1.1",
                   ["role"] = "frontend"
                },
                new TomlTable
                {
                   ["ip"] = "192.168.1.2",
                   ["role"] = "backend"
                }
             }
          };
 
          // ファイルを非同期で書き込む
          using (var writer = new StreamWriter(filePath))
          {
             await tomlTable.WriteToAsync(writer);
          }
       }
       catch (IOException ex)
       {
          Console.WriteLine($"エラー: ファイルの書き込み中にIOエラーが発生: {ex.Message}");
       }
       catch (Exception ex)
       {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
       }
    }
 }


TOMLファイルの修正

以下の例では、指定されたTOMLファイルを読み込み、以下に示す設定を変更して、同じファイルに上書きしている。

  • 非同期処理
    ファイルの読み込みでは、await TOML.ParseAsync(reader)メソッドを使用している。
    ファイルの書き込みでは、await toml.WriteToAsync(writer)メソッドを使用している。
  • ストリーミング処理
    StreamReaderクラスおよびStreamWriterクラスを使用して、ファイルをストリームとして読み書きしている。
  • TOMLファイルの更新
    UpdateConfigメソッドで、指定された変更を行っている。
    • [application]セクション -> "version"キーの値を"1.1.0"に変更する。
    • [logging]セクション -> "level"キーそのものを削除する。
    • [features]セクション -> "enabled"キーの配列から"logout"を削除する。
    • 2つ目の[[servers]]配列 -> "ip"キーの値を"192.168.1.10"に変更する。


 using System;
 using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using Tommy;
 
 class Program
 {
    static async Task Main(string[] args)
    {
       string filePath = "sample.toml";  // 修正するTOMLファイルのパス
 
       try
       {
          // TOMLファイルを非同期で読み込む
          using (var reader = new StreamReader(filePath))
          {
             var toml = await TOML.ParseAsync(reader);
 
             // [application]セクションの"version"キーの値を"1.1.0"に変更
             toml["application"]["version"] = "1.1.0";
 
             // [logging]セクションの"level"キーを削除
             toml["logging"].Remove("level");
 
             // [features]セクションの"enabled"キーの配列から"logout"を削除
             var enabledFeatures = toml["features"]["enabled"].AsArray;
             enabledFeatures.Remove("logout");
 
             // 2つ目の[[servers]]配列の"ip"キーの値を"192.168.1.10"に変更
             var servers = toml["servers"].AsArray;
             if (servers.Count >= 2)
             {
                servers[1]["ip"] = "192.168.1.10";
             }
             else
             {
                Console.WriteLine("警告: 2つ目のサーバ情報が存在しない");
             }
 
             // 変更した内容を非同期でファイルに書き込む
             using (var writer = new StreamWriter(filePath))
             {
                await toml.WriteToAsync(writer);
             }
          }
       }
       catch (FileNotFoundException)
       {
          Console.WriteLine($"エラー: ファイル '{filePath}' が存在しない");
       }
       catch (TomlParseException ex)
       {
          Console.WriteLine($"エラー: TOMLファイルの解析に失敗  行 {ex.Line}, 列 {ex.Column}: {ex.Message}");
       }
       catch (IOException ex)
       {
          Console.WriteLine($"エラー: ファイルの読み書き中にIOエラーが発生: {ex.Message}");
       }
       catch (Exception ex)
       {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
       }
    }
 }


修正後のTOMLファイルを以下に示す。

 # 修正後のTOMLファイル
 
 title = "設定ファイル"       # トップレベルのキー
 
 [user]                     # ユーザ情報のセクション
 name = "山田太郎"
 age = 30
 email = "yamada@example.com"
 
 [application]              # アプリケーション設定のセクション
 version = "1.1.0"          # "1.0.0" から "1.1.0" に変更
 debug_mode = false
 
 [database]                 # データベース接続情報のセクション
 host = "localhost"
 port = 5432
 username = "admin"
 password = "secret"
 
 [features]                 # 機能のオン / オフを制御するセクション
 enabled = ["login", "dashboard"]  # "logout" が配列から削除
 disabled = ["admin_panel"]
 
 [logging]                  # ロギング設定のセクション
 file = "/var/log/app.log"  # "level" キーが削除
 
 [[servers]]                # サーバ情報の配列
 ip = "192.168.1.1"
 role = "frontend"
 
 [[servers]]                # サーバ情報の配列
 ip = "192.168.1.10"        # "192.168.1.2" から "192.168.1.10" に変更
 role = "backend"