「C Sharpの基礎 - CSVファイル」の版間の差分

ナビゲーションに移動 検索に移動
246行目: 246行目:


==== CSVファイルの書き込み ====
==== CSVファイルの書き込み ====
===== 使用例 =====
===== 使用例: 同期処理 =====
以下の例では、StreamWriterクラスを使用して、CSVファイルへ書き込んでいる。<br>
以下の例では、StreamWriterクラスを使用して、CSVファイルへ書き込んでいる。<br>
<br>
<br>
286行目: 286行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
===== 使用例: 非同期処理 =====
以下の例では、上記の例を非同期で処理している。<br>
以下の例では、上記の例を非同期で処理している。<br>
<br>
<br>
323行目: 324行目:
           Console.WriteLine("書き込みエラー: " + ex.Message);
           Console.WriteLine("書き込みエラー: " + ex.Message);
       }
       }
    }
}
</syntaxhighlight>
<br><br>
== CsvHelperライブラリ ==
==== CsvHelperライブラリのインストール ====
RiderまたはVisual StudioからNuGetを使用して、CsvHelperライブラリをインストールする。<br>
* Riderの場合
*# プロジェクトを開く。
*# [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
*# メイン画面下部にある[パッケージ]タブから <u>CsvHelper</u> と入力して検索する。
*# メイン画面下部の右にある[+]ボタンを押下して、CsvHelperライブラリをインストールする。
*: <br>
* Visual Studioの場合
*# プロジェクトを開く。
*# NuGetパッケージマネージャーを開く。
*#* [ツール]メインメニュー - [NuGetパッケージマネージャー]を選択して、[ソリューションのNuGetパッケージの管理]を選択する。
*#* または、ソリューションエクスプローラーでプロジェクトを右クリックして、コンテキストメニューから[NuGetパッケージの管理]を選択する。
*# CsvHelperライブラリを検索する。
*#: NuGetパッケージマネージャーの検索ボックスに <u>CsvHelper</u> と入力して検索する。
*# CsvHelperライブラリのインストール
*#: 検索結果からCsvHelperライブラリを選択して、[インストール]ボタンを押下する。
*# インストールの確認ダイアログが表示されるので、[OK]ボタンを押下してインストールを完了する。
*# 参照の確認
*#: インストールが完了した後、プロジェクトの参照にCsvHelperライブラリが追加されていることを確認する。
*: <br>
* パッケージマネージャーコンソールからインストールする場合
*# プロジェクトを開く。
*# [表示]メインメニュー - [その他のウィンドウ] - [パッケージマネージャーコンソール]を選択して、パッケージマネージャーコンソールを開く。
*# パッケージマネージャーコンソールから、CsvHelperライブラリをダウンロードしてインストールする。
*#: <code>Install-Package CsvHelper</code>
*# ソリューションエクスプローラーのプロジェクトの参照において、CsvHelperライブラリが追加されていることを確認する。
*: <br>
* <code>dotnet</code>コマンドを使用する場合
*# ターミナルを開く。
*# プロジェクトのルートディレクトリに移動する。
*# CsvHelperライブラリをインストールする。
*#: 最新の安定版をインストールする場合
*#: <code>dotnet add package CsvHelper</code>
*#: <br>
*#: バージョンを指定してインストールする場合
*#: <code>dotnet add package CsvHelper --version <バージョン></code>
*#: <br>
*: <u>※注意</u>
*: <u>プロジェクトがGit等のバージョン管理システムを使用している場合、これらの変更がトラッキングされることを確認すること。</u>
*: <u>プロジェクトを再ビルドして、新しく追加されたパッケージが正しく統合されていることを確認することを推奨する。</u>
<br>
プロジェクトにおいて、CsvHelperライブラリを使用する場合は、ソースコードファイルの先頭にusingステートメントを追加する。<br>
<syntaxhighlight lang="c#">
using CsvHelper;
using CsvHelper.Configuration;
</syntaxhighlight>
<br>
CsvHelperはライブラリ非常に柔軟であり、様々なカスタマイズが可能である。<br>
例えば、カスタムマッピングを定義して、CSVファイルの列名とクラスのプロパティ名が異なる場合に対応することができる。<br>
<br>
また、大規模なCSVファイルを扱う場合は、ストリーミング処理を使用することを推奨する。<br>
<br>
==== CSVファイルの読み込み : 同期処理 ====
以下の例では、CsvHelperライブラリを使用して、CSVファイルを同期的に読み込んでいる。
<br>
# StreamReaderクラスを使用して、CSVファイルを開く。
# CsvReaderクラスのインスタンスを生成して、StreamReaderクラスのインスタンスとカルチャ情報を渡す。
# GetRecords<オブジェクト名>メソッドを使用して、CSVファイルの各レコードを任意のオブジェクトにマッピングする。
<br>
また、異なる日付形式やカルチャ設定を指定することもできる。<br>
<br>
// CSVファイルの内容
Id,Name,BirthDate
1,John Doe,1980-01-01
2,Jane Smith,1985-05-15
3,Bob Johnson,1990-12-31
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
      string filePath = "people.csv";
      try
      {
          using (var reader = new StreamReader(filePath))
          using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
          {
            var records = csv.GetRecords<Person>();
            foreach (var person in records)
            {
                Console.WriteLine($"Id: {person.Id}, Name: {person.Name}, Birth Date: {person.BirthDate:d}");
            }
          }
      }
      catch (Exception ex)
      {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
      }
    }
}
</syntaxhighlight>
<br>
==== CSVファイルの読み込み : 非同期処理 ====
以下の例では、CsvHelperライブラリを使用して、CSVファイルをストリーミング処理かつ非同期に読み込んでいる。
<br>
ファイル全体をメモリに読み込む代わりに、1レコードずつ処理するため、大規模なCSVファイルでもメモリ使用量を抑えられる。<br>
ファイルの読み込みと各レコードの処理が非同期で行われるため、アプリケーションの応答性が向上する。<br>
<br>
また、キャンセレーショントークンを追加しているため、長時間の処理をキャンセルすることも可能である。<br>
<br>
<u>await foreach</u>句を使用しているため、.NET Core 3.0以降または.NET 5.0以降で動作することに注意する。<br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.IO;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using CsvHelper;
using CsvHelper.Configuration;
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}
class Program
{
    static async Task Main(string[] args)
    {
      string filePath = "sample.csv";
      using var cts = new CancellationTokenSource();  // キャンセレーショントークンソースの生成
      // キャンセレーショントークンのためのタスクを開始
      var cancellationTask = Task.Run(() =>
      {
          Console.WriteLine("'c'キーを押下して処理をキャンセル");
          if (Console.ReadKey().KeyChar == 'c')
          {
            cts.Cancel();
            Console.WriteLine("キャンセル処理をリクエスト...");
          }
      });
      try
      {
          await ProcessCsvFileAsync(filePath, cts.Token);
      }
      catch (OperationCanceledException)
      {
          Console.WriteLine("読み込み処理がキャンセルされました");
      }
      catch (Exception ex)
      {
          Console.WriteLine($"予期せぬエラーが発生: {ex.Message}");
      }
      // キャンセレーションタスクが完了するまで待機
      await cancellationTask;
    }
    static async Task ProcessCsvFileAsync(string filePath, CancellationToken cancellationToken)
    {
      var configuration = new CsvConfiguration(CultureInfo.InvariantCulture)
      {
          HasHeaderRecord = true,
          MissingFieldFound = null
      };
      using var reader = new StreamReader(filePath);
      using var csv = new CsvReader(reader, configuration);
      var records = csv.GetRecordsAsync<Person>(cancellationToken);
      await foreach (var person in records.WithCancellation(cancellationToken))
      {
          await ProcessPersonAsync(person, cancellationToken);
      }
    }
    static async Task ProcessPersonAsync(Person person, CancellationToken cancellationToken)
    {
      // キャンセレーショントークンの確認
      cancellationToken.ThrowIfCancellationRequested();
      // ここで各Personオブジェクトを非同期に処理
      // 例: データベースへの保存、外部APIの呼び出し等
      await Task.Delay(1000, cancellationToken);
      Console.WriteLine($"Processed: Id: {person.Id}, Name: {person.Name}, Birth Date: {person.BirthDate:d}");
     }
     }
  }
  }

案内メニュー