C Sharpの基礎 - CSVファイル
概要
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);
}
}
}
}
}