「C Sharpの基礎 - TOML」の版間の差分
| 385行目: | 385行目: | ||
           }  |            }  | ||
        });  |         });  | ||
    }  | |||
 }  | |||
 </syntaxhighlight>  | |||
<br>  | |||
==== TOMLファイルの書き込み ====  | |||
以下の例では、Tomlynライブラリを使用して、指定されたTOMLファイルを生成している。<br>  | |||
<br>  | |||
* ストリーミング処理  | |||
*: WriteTomlConfigAsyncメソッド内でFileStreamを使用して、効率的に書き込んでいる。  | |||
*: また、useAsyncプロパティにtrueを指定することにより、非同期I/O操作を有効にしている。  | |||
* TOMLファイルの生成  | |||
*: CreateTomlConfigメソッドで、指定された構造のTOML設定をTomlTableオブジェクトとして作成している。  | |||
*: Toml.FromModelメソッドを使用して、TomlTableオブジェクトをTOML文字列に変換している。  | |||
* ファイルへの書き込み  | |||
*: WriteTomlConfigAsyncメソッド内で、生成されたTOML文字列をファイルに非同期で書き込んでいる。  | |||
<br>  | |||
 <syntaxhighlight lang="c#">  | |||
 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);  | |||
       }  | |||
    }  | |||
 }  | |||
 </syntaxhighlight>  | |||
<br>  | |||
==== TOMLファイルの修正 ====  | |||
以下の例では、Tomlynライブラリを使用して、以下に示すTOMLファイルの値を修正している。<br>  | |||
<br>  | |||
* ストリーミング処理  | |||
*: ReadTomlConfigAsyncおよびWriteTomlConfigAsyncメソッド内でFileStreamを使用して、効率的に読み書きしている。  | |||
*: また、useAsyncプロパティの値をtrueを指定することにより、非同期I/O操作を有効にしている。  | |||
* TOMLファイルの更新  | |||
*: UpdateConfigメソッドで、指定された変更を行っている。  | |||
*:* [application]セクション -> "version"キーの値を"1.1.0"に変更する。  | |||
*:* [logging]セクション -> "level"キーそのものを削除する。  | |||
*:* [features]セクション -> "enabled"キーの配列から"logout"を削除する。  | |||
*:* 2つ目の<nowiki>[[servers]]</nowiki>配列 -> "ip"キーの値を"192.168.1.10"に変更する。  | |||
* ファイルへの書き込み  | |||
*: WriteTomlConfigAsyncメソッド内で、更新されたTOMLデータをファイルに非同期で書き込んでいる。  | |||
<br>  | |||
 <syntaxhighlight lang="c#">  | |||
 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);  | |||
       }  | |||
     }  |      }  | ||
  }  |   }  | ||
2024年9月20日 (金) 04:10時点における版
概要
TOML (Tom's Obvious, Minimal Language) は人間や機械にとって読みやすく、解析しやすい設定ファイル形式である。
TOMLファイルは、設定ファイルやデータ保存の効率的な方法として注目されている。
TOMLファイルの特徴として、JSON形式よりも人間が読みやすい点が挙げられる。
また、XMLと比べてシンプルな構造を持ちながら、十分な表現力を備えている。
TOMLファイルの構造は、キーと値のペアを基本としており、セクションを使用して階層構造を表現することもできる。
これにより、複雑な設定やデータ構造を直感的に表現することができる。
C#でTOMLファイルを使用する場合は、一般的に、サードパーティ製ライブラリを使用する。
以下に示すライブラリを使用することにより、TOMLファイルの読み書きを簡単に行うことができる。
- Tomlyn
- ライセンス : 2条項BSDライセンス
 - URL : https://github.com/xoofx/Tomlyn
 
 - Tommy
- ライセンス : MITライセンス
 - URL : https://github.com/dezhidki/Tommy
 
 - Tomlet
- ライセンス : MITライセンス
 - URL : https://github.com/SamboyCoding/Tomlet
 
 - Nett (ただし、2020年以降は開発が停止)
- ライセンス : MITライセンス
 - URL : https://github.com/paiden/Nett
 
 
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ライブラリのGithub
 
Tomlynライブラリのインストール
RiderまたはVisual StudioからNuGetを使用して、Tomlynライブラリをインストールする。
- Riderの場合
- プロジェクトを開く。
 - [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
 - メイン画面下部にある[パッケージ]タブから Tomlyn と入力して検索する。
 - メイン画面下部の右にある[+]ボタンを押下して、Tomlynライブラリをインストールする。
 
 - Visual Studioの場合
- プロジェクトを開く。
 - NuGetパッケージマネージャーを開く。
- [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
 - または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
 
 - Tomlynライブラリを検索する。
- NuGetパッケージマネージャーの検索ボックスに Tomlyn と入力して検索する。
 
 - Tomlynライブラリのインストール
- 検索結果からTomlynライブラリを選択して、[インストール]ボタンを押下する。
 
 - インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
 - 参照の確認
- インストールが完了した後、プロジェクトの参照にTomlynライブラリが追加されていることを確認する。
 
 
 - パッケージマネージャーコンソールからインストールする場合
- プロジェクトを開く。
 - [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
 - パッケージマネージャーコンソールから、Tomlynライブラリをダウンロードしてインストールする。
Install-Package Tomlyn
 - ソリューションエクスプローラーのプロジェクトの参照において、Tomlynライブラリが追加されていることを確認する。
 
 dotnetコマンドを使用する場合- ターミナルを開く。
 - プロジェクトのルートディレクトリに移動する。
 - 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"に変更する。
 
 
 - UpdateConfigメソッドで、指定された変更を行っている。
 - ファイルへの書き込み
- 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);
       }
    }
 }