[C#]テキスト/CSV/Excelのファイルを読み取る方法

# はじめに
この記事は新人プログラマーもしくは基本的な文法を一通り勉強した方が、C#でテキスト/CSV/Excelファイル、拡張子で言えば.txt/.csv/.xlsxのファイルを読み取りたいときに参考になればと思って書きました。
私自身もC#を勉強中ですので切磋琢磨できればと思います。

・Windows/Visual Studioの環境でコンソールアプリケーションもしくはフォームアプリケーション（デスクトップアプリケーション）開発を想定しています。
・フレームワークは.NET Framework 4.7.2
・とにかく難しいことは置いといてファイル読み取ってとりあえず読み取った値を出力したい方向けです。

# テキストファイル(.txt)を読み取る
まずは読み取りたいテキストファイル(textfile.txt)をデスクトップに作っておきます。
中身は、カンマで区切って２文を書いてます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408792/061e3d38-c8f9-5441-0328-abb43c0a8186.png)

C#でテキストファイルを読み込む場合は、StreamReaderクラスを使用します。
今回は、テキストファイルを読み込んでコンソール画面に出力します。
# txtサンプルコード

```Read_txt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Read_txt
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //読み込むtxtファイルのパスを指定して開く
                using (StreamReader sr = new StreamReader(@"C:\Users\hiroki\Desktop\textfile.txt"))
                {
                    //末尾まで繰り返す
                    while (!sr.EndOfStream)
                    {
                        //1行づつ読み取る。
                        string line = sr.ReadLine();
　　　　　　　　　　　　　//コンソールに出力する
                        Console.WriteLine(line);
                    }
                }
            }
            //System.IO.FileNotFoundExceptionを省略して
            catch(FileNotFoundException e)
            {
                Console.WriteLine(e.Message);
            }
            //System.Exceptionを省略して
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }
    }
}


```
出力結果
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408792/116c17eb-d7d0-fd03-2d26-c42fb9b65013.png)


- StreamReaderクラスを使用するためコードの冒頭にusing System.IO;の名前空間を宣言しておきます。
- StreamReaderを使用する際は何のファイルがどこにあるか(パス)を指定する必要があります。
パスの探し方はテキストファイルのプロパティに書いてあります。プロパティの場所の後に￥を入れテキストファイルの名前と拡張子を入れてください。


- try~catch構文を使い例外処理を行っています。つまり、例外が発生しそうなコードをtryブロックで囲み、catchブロックで例外が発生した時の処理をするようにしています。ここではtryブロックでアクセスしようとしたファイルが存在しなかったり、アクセス権限が与えられていなかったなどの例外が発生すると、catchブロックでエラーを出力するようにしています。
- StreamReaderクラスは、指定されたファイルが存在しない場合に、FileNotFoundException(ファイルが見つかりません。)例外を出力します。その他の例外はこちら(https://docs.microsoft.com/ja-jp/dotnet/api/system.io.streamreader.-ctor?view=netframework-4.8#System_IO_StreamReader__ctor_System_IO_Stream_) を参照してください。
- すべての例外クラスは、System名前空間のExceptionクラスを基底クラスとします。簡単にいうと、ファイルが存在しない以外の全ての例外を捕捉するために一般的な例外であるSystem.Exceptionがあります。
- catchブロックでは、指定された例外変数ここではeを介して例外クラスにアクセスします。例外クラスのプロパティとして例外メッセージを返すMessageプロパティを使用しています。
- tryブロックの中にusing命令を入れ、入れ子のようにしています。using命令はファイルを開いた後は必ず閉じるようにします。これはファイルのような共有リソースは、利用したら解放することが必要だからです。解放されなかった場合、メモリーを圧迫したり、他からの利用を妨げられる原因となるためです。Closeメソッドでファイルを記述することもできますが、何らかのエラーでCloseメソッドまでたどり着けず、アプリが終了する場合が考えられるので、ブロックを抜けたところで確実にファイルをクローズしてくれるusing命令を使用するのが無難です。
- 他のメソッドは[こちら](https://www.sejuku.net/blog/85579)が詳しいです。

# CSVファイルを読み取る

CSVファイルもStreamReaderクラスを使用します。
エクセルでA1辺りのセルに適当に文字を書いてください。このときセルにカンマは必要ありません。名前を付けて保存する際に拡張子をCSVに指定してください。

CSVファイルを読み込みコンソールに出力するコードです。
# CSVサンプルコード

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Read_CSV
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //読み込むcsvファイルのパスを指定して開く
                using (StreamReader sr = new StreamReader(@"ファイルのパス"))
                {
                    while (!sr.EndOfStream)
                    {
                        //1行づつ読み取る。カンマも読み取っている。
                        string line = sr.ReadLine();
                        //カンマで区切った文の塊を格納する
                        string[] values = line.Split(',');

                        foreach (var list in values)
                        {
                            Console.WriteLine("{0}", list);
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }  
        }
    }
}

```

- CSVとはカンマごとに区切られた文字や値の塊です。したがって、string[] values = line.Split(',');ではカンマごとに塊を配列に格納します。文字として読み取るのでstring型になっています。
- 配列として塊があるので全配列を扱うforeach構文を使いコンソールに出力します。

# エクセルファイル(.xlsx)を読み取る

最後にエクセルファイルの読み込みです。エクセルファイルを読み込むにはいくつかの方法がありますが、初心者が扱うには手に負えない複雑なものもあります。ここでは私が最も簡単だと思うサードパーティが提供しているClosedXMLというライブラリを使います。

ClosedXMLというライブラリを使うための準備などを[こちら](https://www.atmarkit.co.jp/ait/articles/1810/24/news016.html#about)を参考にしてください。

エクセルファイルをデスクトップに用意しそのセル情報を読み込んだコードです。
A1とA2に文字を記入しています。

# エクセルサンプルコード

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClosedXML.Excel;

namespace Read_xlsx
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //読み込むxlsxのファイルパスを指定して開く
                using (var workbook = new XLWorkbook(@"エクセルファイルのパス名"))
                {
                    //ワークシートを取得する
                    var worksheet = workbook.Worksheet("シート名");
                    //位置を指定してセルを取得する
                    var cellA1 = worksheet.Cell("A1");//A1のセルを取得する
                    var cellA2 = worksheet.Cell(2, 1);//2行目の1列のセルを取得する
                    Console.WriteLine(cellA1.Value);
                    Console.WriteLine(cellA2.Value);
                }
               
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
        }
    }
}

```

-  コードの冒頭でusing ClosedXML.Excel;を宣言してください。他の方の昔の記事でusing ClosedXML;だけの宣言で終わってますが、エラーが出ますので注意してください。
-  xlsxのファイルのクラスを宣言し、ワークシートを指定します。
- ファイルのパス名はエクセルファイルのプロパティからコピペしてください。
- 今回は指定したワークシートのセルA1とA2だけに文字が格納されているとしてコンソールに出力しています。

# 最後に
テキストとCSVファイルを読み取るStreamReaderクラスやその他のメソッドは主に独習C#を参考にしました。
エクセルの読み取りは他の記事をググって参考にしました。あまり体系的に書かれているものがなかったので今回まとめてみました。