C Sharpの基礎 - CSVファイル

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2024年9月14日 (土) 22:23時点におけるWiki (トーク | 投稿記録)による版 (ページの作成:「== 概要 == CSV (Comma-Separated Values) は、テキストベースのシンプルなファイル形式である。<br> 各行がデータレコードを表しており、フィールドはカンマ (または他の区切り文字) で区切られている。<br> <br> C#でCSVファイルを読み込む場合は、主に<code>System.IO</code>名前空間のクラスを使用する。<br> <code>File.ReadAllLines</code>メソッドを使用してファイルの全…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

概要

CSV (Comma-Separated Values) は、テキストベースのシンプルなファイル形式である。
各行がデータレコードを表しており、フィールドはカンマ (または他の区切り文字) で区切られている。

C#でCSVファイルを読み込む場合は、主にSystem.IO名前空間のクラスを使用する。
File.ReadAllLinesメソッドを使用してファイルの全行を文字列配列として読み込み、次に、String.Splitメソッドで各行をフィールドに分割する。

CSVファイルへ書き込む場合は、StreamWriterクラスを使用して行うことができる。
各フィールドをカンマで連結して、WriteLineメソッドで1行ずつファイルに書き込む。

より複雑なCSV操作には、サードパーティのライブラリを利用することも可能である。
CsvHelperライブラリは人気のあるライブラリであり、読み書きの柔軟性が高く、大規模なCSVファイルの処理に適している。

CSVファイルを扱う時の注意点として、フィールド内にカンマが含まれる場合の処理がある。
このような場合、フィールドを引用符で囲むなどの対策が必要である。

また、文字エンコーディングの問題にも注意が必要であり、特に異なる言語や地域のデータを扱う場合は重要である。

C#のLINQを活用すると、CSVデータの効率的な操作や分析が可能になる。
例えば、特定の条件に合うレコードのフィルタリング、あるいは、データの集計等を簡単に行うことができる。

セキュリティの観点からは、外部ソースからのCSVファイルを扱う場合には注意が必要である。
悪意のあるデータが含まれている可能性があるため、適切な入力検証とサニタイズを行うことが重要である。

パフォーマンスを考慮する場合、大規模なCSVファイルを扱う場合はストリーミング読み取りを検討する。
これにより、メモリ使用量を抑えつつ効率的に処理を行うことができる。


CSVファイル

CSVファイルを読み込むには、.NET Framework 2.0で追加されたTextFieldParserクラス(Microsoft.VisualBasic.FileIO名前空間)を使用する。
TextFieldParserクラスを使用することで、CSVファイルを読み込み、各行の各フィールドの文字列を簡潔に取得することができる。

CSVファイルを読み込む

TextFieldParserクラスを使用してCSVファイルを読み込むには、
まず、TextFieldParserクラスのコンストラクタに処理するCSVファイルを指定して、インスタンスを生成する。
CSVファイルに日本語が含まれている場合は、文字コードを指定する。

 using System.Text;
 using Microsoft.VisualBasic.FileIO;
 
 var parser = new TextFieldParser(@"hoge.csv", Encoding.GetEncoding("Shift_JIS"));  // 文字コードはShift-JISを指定する


次に、TextFieldTypeプロパティにFieldType.Delimitedを指定する。
もし、FieldType.FixedWidthを指定する場合、フィールドが固定幅のファイルも扱うことができる。

また、SetDelimitersメソッドを使用して、区切り文字を指定する。(複数の区切り文字が指定可能)
CSVファイルの場合は、,(カンマ)を指定する。

 parser.TextFieldType = FieldType.Delimited;
 parser.SetDelimiters(",");  // 区切り文字はカンマを指定する


TextFieldParserクラスのReadFieldsメソッドを実行するごとに、CSVファイルを1行ずつ読むことができる。
ReadFieldsメソッドは、読み込んだレコードの全てのフィールドを文字列配列に変換して返す。
次のレコードが存在するかどうかはEndOfDataプロパティにより判定できるため、ループにより、CSVファイル全体を処理できる。

 while (!parser.EndOfData)
 {
     // 配列rowの要素は読み込んだレコードの各フィールドの値
     string[] row = parser.ReadFields();  // 1レコード読み込む
 }


CSVファイルを読み込み表示する

以下の例では、hoge.csvファイルを読み込み、各フィールドを切り出してタブ区切りで画面に出力する。
改行文字および空白文字がどのように処理されるかを分かりやすくするために、それぞれをnと_に置換して出力している。

  • HasFieldsEnclosedInQuotesプロパティ
    フィールドに改行やデリミタを含める為に引用符を使っているようなフォーマットを考慮する場合は、
    HasFieldsEnclosedInQuotesプロパティをtrueに設定する。(初期値はtrue)
  • TrimWhiteSpaceプロパティ
    フィールドの前後の空白文字を削除しない場合は、TrimWhiteSpaceプロパティをfalseに設定する。(初期値はtrue)


 using System;
 using System.Text;
 using Microsoft.VisualBasic.FileIO;
 
 class CSVParser
 {
    static void Main()
    {
       using (var parser = new TextFieldParser("text.csv", Encoding.GetEncoding("Shift_JIS")))
       {
          parser.TextFieldType = FieldType.Delimited;  // フィールドはデリミタにより区切る(可変)
          parser.Delimiters = new[] {","};             // 区切り文字を指定
          parser.CommentTokens = new[] {"#"};          // #で始まる行をコメントとする
 
          // parser.HasFieldsEnclosedInQuotes = false; // 引用符で括られたフィールドを持つか指定
          // parser.TrimWhiteSpace = false;            // フィールドの前後に含まれる空白を削除するか指定
 
          while (!parser.EndOfData)
          {
             try
             {
                string[] row = parser.ReadFields(); // 1行読み込む
                foreach (string field in row)
                {
                   field = field.Replace("\r\n", "n"); // 改行をnに置換
                   field = field.Replace(" ", "_");    // 空白を_に置換
                   Console.Write(field + "\t");    // タブ区切りで出力
                }
                Console.WriteLine();
             }
             catch(Exception ex)
             {
                Console.WriteLine(ex.Message);
             }
          }
       }
    }
 }