.net column

.NET開発者のためのブログメディア

C#によるCSVの読み込み方法を解説!|文字化けした場合の対処方法を理解しよう

2020年09月30日
SE
C#のCSVファイルを読み込むと文字化けしてしまうのですが。
PM
CSVファイルの文字コードがUTF-8ではなく、日本のWindows環境で使用されるShift_JISになっているためです。ソースの先頭に「using System.Text;」を追加し、usingの箇所をサンプルのように直してください。

C#のCSV読み込みとは?

CSVとはComma Separated Valueの略で、直訳すると「カンマ(,)で区切られた値」という意味です。そしてCSVファイルとはカンマ区切りの値が記述されている、ファイル拡張子が.csvのテキストファイルのことです。

 

C#ではそのCSVファイルの読み込みが簡単にできます。この記事でそのやり方や注意点を紹介するので、CSVの処理の方法を調べている人は是非ご覧ください。

CSV読み込みのサンプル

以下はC#でCSV読み込みを行うサンプルです。これを実行する場合、ソースの先頭に「using System.IO;」を追加してください。

 

using (StreamReader reader = new StreamReader(“”C:\\test\\test.csv””))
{
while (!reader.EndOfStream)
{
string l = reader.ReadLine();
string[] ary = l.Split(‘,’);

 

for(int i = 0; i < ary.Length; i++)
{
Console.WriteLine(ary[i]);
}
}
}

usingを使用すればCloseし忘れが無くなるので安心

上のC#サンプルの解説をします。まずusingですが、これを使用するとCloseが必要な場合に自動的に行ってくれます。今回使用しているStreamReaderのような、ファイルの読み込みを行う機能は必ず最後にCloseが必要ですが、usingで忘れるのを防止できます。

 

StreamReaderで指定したCSVファイルを開いた後は、次のwhileループでCSVの読み込みを行います。EndOfStreamが来ない間は続ける、と言うことは、ファイルの最後まで読み込むということです。

String.Splitでカンマ区切りができる

whileループ内ではReadLineにより一行読み込みます。改行コードがある所まで読み込むということです。そして読み込んだ文字列に対してSplitでカンマ区切りを行い、String型の配列に格納します。

 

そしてカンマ区切りを行った配列の中身をコンソールに表示します。以下のような内容のCSVファイルをこのC#のサンプルで読み込むと、

 

あああ,えええ,123,おおお
いい,ううううう,777

 

以下のように表示されます。

 

あああ
えええ
123
おおお
いい
ううううう
777

文字化けした場合の対処

なお、このC#サンプルを実行して読み込みを行っても、以下のように表示されてしまう人もいるかもしれません。

 

??????
??????
123
??????
????
??????????
777

 

これは文字化けしています。考えられる理由としては、CSVファイルの文字コードがUTF-8ではなく、日本のWindows環境で使用されるShift_JISになっていることです。それを解消するには、ソースの先頭に「using System.Text;」を追加し、usingの箇所を以下のように直してください。

 

using (StreamReader reader = new StreamReader(“”C:\\test\\test.csv””, Encoding.GetEncoding(“”Shift_JIS””)))

Shift_JISが使えない時の対処法

上の様に対処すると、「’shift_jis’ is not a supported encoding name. 」といった例外が発生してしまうかもしれません。その場合は動作環境をShift_JISに対応させる必要があります。

 

その方法は、まずVisual Studioのソリューションエクスプローラーの「依存関係」を右クリックして、「NuGetパッケージの管理」をクリックしてください。そして検索フォームにSystem.Text.Encoding.CodePagesと入力してください。

System.Text.Encoding.CodePagesでShift_JISが使える

するとSystem.Text.Encoding.CodePagesが検索結果に出てきます。それをインストールしてください。終了すると、ソリューションエクスプローラーの依存関係・パッケージにSystem.Text.Encoding.CodePageが追加されます。

 

最後にusingの処理の前に、

 

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

 

を追加します。これでShift_JISが使えるようになります。C#はWindows以外の環境も想定しているため、初期状態ではShift_JISに対応していないのです。

値にカンマを含むCSVへの対応は?

CSVの読み込みは、ここまでのやり方では上手くいかない場合があります。CSVファイルの値に,を含めたい場合は、区別するために””””で囲むという決まり事があります。しかしここまでのC#サンプルはそのルールに対応できません。以下のような内容のCSVファイルの読み込みを行った場合、

 

この.はピリオドです,””この,はカンマです””,この、は読点です

 

サンプルの結果は以下になってしまいます。値の中に含まれるカンマの所で区切られてしまい、””も表示されてしまいます。

 

この.はピリオドです
“”この
はカンマです””
この、は読点です

TextFieldParserのクラスで値の中のカンマに対応できる

値に,を含むCSVに対応するにはどうしたらいいのでしょうか。やり方としてはこのサンプルを改良して、””が来たら,で区切るのを止めて、また””が来たら区切るようにする、といった処理を追加することです。

 

そういった処理を自分で作るのはC#のスキル向上につながりますし、大いにやるべきでしょう。ただそういったプログラムがすでに作られているのなら、あるものを再利用して手間を減らしたいところです。

 

実は””””に対応しているCSV読み込み機能はすでにあります。それはTextFieldParserのクラスです。

TextFieldParserのクラスサンプル

以下がTextFieldParserのクラスを使用したC#のCSV読み込みのサンプルです。ソースの先頭には「using Microsoft.VisualBasic.FileIO;」を記述してください。

 

using (TextFieldParser parser = new TextFieldParser(“”C:\\test\\test.csv””))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(“”,””);
parser.HasFieldsEnclosedInQuotes = true;
parser.TrimWhiteSpace = false;

 

while (!parser.EndOfData)
{
string[] ary = parser.ReadFields();

 

for(int i = 0; i < ary.Length; i++)
{
Console.WriteLine(ary[i]);
}
}
}

TextFieldParserは最初に設定が必要

追加したusingからわかるように、TextFieldParserはVisualBasicの機能です。最新のVisual Studio環境では、VisualBasicの機能は追加設定無しで使用できます。それではこのC#サンプルを解説しましょう。

 

前のサンプルと違う点は、最初にTextFieldParserの設定を行っていることです。まずTextFieldTypeにFieldType.Delimitedを設定していますが、これは区切り型のファイルを読み込むという意味です。

 

TextFieldParserはCSV形式以外のファイルにも対応できるのでこの設定が必要なのです。

HasFieldsEnclosedInQuotesで””””で囲まれた値に対応可能

次にSetDelimitersに””,””を設定しています。TextFieldParserはカンマ以外で区切られたファイルにも対応できるのです。そしてHasFieldsEnclosedInQuotesにtrueを設定しています。これは””で囲まれて,を持つ値に対応できる機能を使用するという意味です。

 

最後の設定としてTrimWhiteSpaceにfalseを設定しています。これをtrueにすると値の前後にスペースが入っている場合に除去してくれます。読み込みの処理ではReadFieldsで文字列の配列を取得します。Splitで区切るような処理はやってくれるので不要です。

 

このサンプルで上手くいかなかったCSVファイルを読み込むと、以下のように表示されます。

 

この.はピリオドです
この,はカンマです
この、は読点です

SE
すでにあるプログラムがあるなら、有効に利用すればいいのですね。
PM
そのとおりです。自作してもいいのですが、すでにある機能は有効活用して手間を省くことも必要です。

TextFieldParserを使用してCSVを正しく読み込もう

C#によるCSVファイルの読み込みについて解説しましたが、ご理解頂けましたでしょうか。

 

StreamReaderでカンマ区切りの読み込みを自作してもいいのですが、すでにある機能は有効活用して手間を省きましょう。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

求人一覧

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)