【C#】フォルダ内のファイルの場所を特定するアプリを作りたい

# はじめに
仕事でフォルダ内のファイルを探すのって、めんどくさい時ありますよね？
特に、数十ものファイルがバラバラに散らばってたりすると、手で全部探すのは大変。
今回はC#の勉強も兼ねて、自分用のアプリを作ってみることにしました。
これで手動でのファイル探しの手間が省けるし、なんといっても楽しいですよね！

# 環境
- Windows10
- Visual Studio 2022

# どんな感じにするか
- 目標のフォルダと対象ファイルのリストが記載されたテキストファイルをそれぞれ用意。
- これらのファイルを読み込み、リストに記載されたファイルの場所を特定して、それぞれのファイルのフルパスを返す。

### 作るクラス
|クラス|内容|
|---|---|
|LineProcesser|１行ずつ処理する|
|FilePathLocator|ファイルの場所を探し、フルパスを返す|
|TextWrite|結果をファイル出力する|
|Program|各処理を実行するメインのクラス|


# textファイルを読み込んで１行ずつ処理する

テキストファイルを読み込み↓
```c#
string[] readText = File.ReadAllLines("C:\\YoutPath\\TargetFiles.txt");
```

繰り返し処理で１行ずつ処理する↓
```c#
foreach(string s in readText)
{
    Console.WriteLine(s);
}
```

全体↓
```c#
using System;
using System.IO;

namespace TextReader
{
    internal class LineProcesser
    {
        static void Main(string[] args)
        {
            string line;

            // 読み込むテキストファイル
            string[] readText = File.ReadAllLines("C:\\YoutPath\\TargetFiles.txt");
            
            // ファイルの終わりまで読み込む
            foreach(string s in readText)
            {
                Console.WriteLine(s);
            }
        }
    }
}

```

# ファイルがフォルダ内のどこにあるかを探す
Directory.GetFileメソッドを使う↓
```c#
// 検索するフォルダーパス 
string folderPath = @"C:\YoutPath\target_folder";

// 検索するファイル名
string targetFileName = "aaa.txt";

// フォルダ内の全てのファイルパスを取得
string[] filePaths = Directory.GetFiles(folderPath, targetFileName, SearchOption.AllDirectories);
```
```SearchOption.AllDirectories```でフォルダ内のすべてのサブフォルダも検索対象に含めることが出来る

↑をfor文で表示↓
```c#
foreach (string filePath in filePaths)
{
    Console.WriteLine($"{filePath}");
}
```
全体↓
```c#
using System;
using System.IO;

namespace TextReader
{
    internal class FilePathLocator
    {
        static void Main(string[] args)
        {
            // 検索するフォルダーパス 
            string folderPath = @"C:\Users\sengoku_hi\Desktop\target_folder";

            // 検索するファイル名
            string targetFileName = "aaa.txt";

            // フォルダ内の全てのファイルパスを取得
            string[] filePaths = Directory.GetFiles(folderPath, targetFileName, SearchOption.AllDirectories);
            
            // ファイルが見つからなかった場合はパスを表示し、見つからなかった場合はメッセージを表示
            if (filePaths.Length > 0)
            {
                Console.WriteLine("以下のパスにファイルが見つかりました");
                foreach (string filePath in filePaths)
                {
                    Console.WriteLine($"{filePath}");
                }
            }
            else
            {
                Console.WriteLine("指定したファイルは見つかりませんでした");
            }

        }
    }
}

```

# ファイル出力
StreamWriteを使う
usingステートメントを使用しているため、StreamWriterの処理が終了すると自動的にファイルが閉じられる


```c#
string outPutFile = "out.csv";
string outTxt = "aaa,aaa\nbbb,bbb";

using (StreamWriter sw = new StreamWriter(outPutFile, false, Encoding.GetEncoding("shift_jis")))
{
    sw.WriteLine(outTxt);
}
```


# 全体

```c#
using System;
using System.IO;
using System.Text;


//１行ずつ処理する
public class LineProcesser
{
    public static string GetTargetFolder(string targetFoderConfigPath)
    {
        // 設定したターゲットフォルダーを読み込む
        StreamReader sr = new StreamReader(targetFoderConfigPath);
        string targetFolder = sr.ReadLine();
        return targetFolder;
    }
    public static string GetTargetFilePaths(string targetFileConfigPath, string targetFolder)
    {
        StringBuilder sb = new StringBuilder();

        // 読み込むテキストファイル
        string[] readText = File.ReadAllLines(targetFileConfigPath);

        
        // ファイルの終わりまで読み込む
        foreach(string s in readText)
        {
            sb.Append(FilePathLocator.FindFilePaths(targetFolder, s) + "\n");
        }


        return sb.ToString();
    }
}


//ファイルがどこにあるのかを探し、そのパスを返す
public class FilePathLocator
{
    public static string FindFilePaths(string targetFolderConfigPath, string targetFileName)
    {
        StringBuilder sb = new StringBuilder();

        // フォルダ内の全てのファイルパスを取得
        string[] filePaths = Directory.GetFiles(targetFolderConfigPath, targetFileName, SearchOption.AllDirectories);

        // ファイルが見つからなかった場合はパスを表示し、見つからなかった場合はメッセージを表示
        if (filePaths.Length > 0)
        {
            Console.WriteLine($"以下のパスに{targetFileName}が見つかりました");
            foreach (string filePath in filePaths)
            {
                Console.WriteLine($"{filePath}");
                sb.Append($"{targetFileName},{filePath}\n");
            }
        }
        else
        {
            Console.WriteLine($"{targetFileName}は見つかりませんでした");
            sb.Append($"{targetFileName},指定したファイルは見つかりませんでした");
        }

        return sb.ToString();
    }
}

public class TextWrite
{
    public static void OutPutText(string outPutFile, string outTxt)
    {
        using (StreamWriter sw = new StreamWriter(outPutFile, false, Encoding.GetEncoding("shift_jis")))
        {
            sw.WriteLine(outTxt);
        }
    }
}


class Program
{
    static void Main()
    {
        // コンフィグファイルの場所とアウトプットファイルの場所を必要に応じて編集してください
        string currentDirectory = Directory.GetCurrentDirectory();
        string configDirectory = Path.Combine(currentDirectory, "config");
        string outputDirectory = Path.Combine(currentDirectory, "OutPut");

        string targetFileConfigPath = Path.Combine(configDirectory, "targetFileNames.txt");
        string targetFolderConfigPath = Path.Combine(configDirectory, "targetFolder.txt");
        string outPutFile = Path.Combine(outputDirectory, "outPut.csv");

        string targetFolder = LineProcesser.GetTargetFolder(targetFolderConfigPath);
        string outTxt = LineProcesser.GetTargetFilePaths(targetFileConfigPath, targetFolder);
        outTxt = $"ファイル名,フルパス\n{outTxt}";
        TextWrite.OutPutText(outPutFile, outTxt);

        Console.WriteLine("完了しました。何かキーを教えてください...");
        Console.ReadKey(); // ユーザーが何かキーを押すまで待機
    }
}
```

# exe化
ビルドを行うと、binフォルダにexeが出来る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610435/631bd570-2fc2-cae2-911a-f463b04c3a93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610435/8b398dbd-1fae-609d-a56a-b7f7d5c53237.png)



# おわりに
c#案件２か月目でまだまだ初心者で、あまりよくない書き方をしていたらすいません。
（よけらばコメント頂けると幸いです。）
最後まで読んでいただきありがとうございました。

# 参考サイト
https://learn.microsoft.com/ja-jp/dotnet/standard/io/how-to-write-text-to-a-file