🌟

全ファイル検索を実装しました。 日記

に公開

C# コンソール駆動の全ファイル検索ソフト(開発進捗)

概要

指定したフォルダの中身をすべて取得し、ファイル名で検索するソフト。

ファイルパスのリストを取得することに多くの時間を要する。

C:/のすべてのファイルを取得するには、1分ほど待つ必要がある。

検索は、高速化をしていなくともある程度の速度が出る。

どのようにユーザが欲しいデータを判定するかのほうが大変な印象。

Cのすべてを取得した場合は、検索に引っかかるものが多すぎて使い物にならない。

文書を保存しているフォルダを指定するくらいが望ましいと思う。

仕様

mode 0       読み込みモード フォルダパスを指定 読み込みが完了すると、自動でmode 1に
mode 1    検索モード そのまま検索できる

.c コンソールクリア
.h quary 読み込み 履歴から読み込みする 例えば、c:/user/tagaha/jsjss/ppp をmode 0で読み込んだことがある場合、.h pppを入力することで、すぐに検索できるようになる。
.o id ファイルを開く
.f id フォルダを開く

 

履歴は、アプリケーションのフォルダの、historyに格納されます。

開発途中ではあるが、コードを載せておく。

アクセス権限のないファイルを読みに行き、エラーで止まるという問題が、
ファイル取得にはつきものだ。

解決するために多くの時間を使用したので、
参考にしてください。



using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics; // OrderByDescendingを使用するために追加

public class Scanner
{
    // ... GetAllFilesRecursiveメソッドは変更なし ...
    private static void GetAllFilesRecursive(string path, List<string> fileList)
    {
        fileList.Add(path);
        try
        {
            fileList.AddRange(Directory.GetFiles(path, "*").Where(s =>!s.EndsWith(".dll") && !s.EndsWith(".jpg" ) && !s.EndsWith(".png") && !s.EndsWith(".svg")));
            
        }
        catch (UnauthorizedAccessException) { Console.WriteLine($"[スキップ] アクセス権がありません: {path}"); }
        catch (Exception ex) { Console.WriteLine($"[エラー] ファイル取得中にエラーが発生しました: {path} ({ex.Message})"); return; }

        try
        {
            foreach (var dir in Directory.GetDirectories(path))
            {
                GetAllFilesRecursive(dir, fileList);
                
            }
        }
        catch (UnauthorizedAccessException) { Console.WriteLine($"[スキップ] アクセス権がありません: {path}"); }
        catch (Exception ex) { Console.WriteLine($"[エラー] サブディレクトリ取得中にエラーが発生しました: {path} ({ex.Message})"); }
    }

    /// <summary>
    /// パス文字列をファイル名/フォルダ名として使用できる安全な文字列に変換します。
    /// </summary>
    /// <summary>
    /// パス文字列をファイル名/フォルダ名として使用できる安全な文字列に変換します。
    /// </summary>
    private static string SanitizePath(string path)
    {
        string invalidChars = new string(Path.GetInvalidFileNameChars());
        invalidChars += ":"; // ドライブ名(C:)のコロンも置換対象に含める
        foreach (char c in invalidChars)
        {
            path = path.Replace(c.ToString(), "_");
        }
        return path;
    }

    public static void Main(string[] args)
    {
        string[] files = [];
        int mode = 0;

        // アプリケーションフォルダ内に履歴保存用のベースフォルダを作成
        string historyBaseDir = Path.Combine(AppContext.BaseDirectory, "history");
        Directory.CreateDirectory(historyBaseDir);

        while (true)
        {
            var read_text = Console.ReadLine().Trim(); // 前後の空白を除去
            if (read_text == "") {
                continue;
            }
            

         

            if (read_text.Trim().ToLower() == ".c") {
                Console.Clear();
                continue;
            }
            var array = read_text.Split(new[] { ' ' }, 2);
            if (array.Length == 2)
            {
                string command = array[0].Trim().ToLower();
                string argument = array[1].Trim().Trim('"');

                if (command == "mode")
                {
                    mode = int.Parse(argument);
                    Console.WriteLine("\n\n" + "now mode  " + mode);
                    continue;
                }
                
                if (command == ".o" || command == ".f")
                {
                    // (o, f コマンドの処理は変更なし)
                    if (int.TryParse(argument, out int fileIndex) && fileIndex >= 0 && fileIndex < files.Length)
                    {
                        string filePath = files[fileIndex];
                        if (command == ".o" && File.Exists(filePath))
                        {
                            new System.Diagnostics.Process { StartInfo = new System.Diagnostics.ProcessStartInfo(filePath) { UseShellExecute = true } }.Start();
                        }
                        else if (command == ".f" )
                        {
                            string dir = "";
                            if (Directory.Exists(filePath)) {
                                dir = filePath;
                            }
                            else { 
                                dir = Path.GetDirectoryName(filePath);
                            }
                            if (Directory.Exists(dir)) {
                                new System.Diagnostics.Process { StartInfo = new System.Diagnostics.ProcessStartInfo(dir) { UseShellExecute = true } }.Start();
                            }
                            
                            
                        }
                    }
                    continue;
                }
                else if (command == ".h")
                {
                    string targetPath = argument;
                    try
                    {
                        string search_path = "";
                       
                        string[] names = System.IO.Directory.GetDirectories(
    historyBaseDir, "*", System.IO.SearchOption.AllDirectories);
                        for (var i = 0;i < names.Length;i++)
                        {
                            if (names[i].IndexOf(targetPath, StringComparison.OrdinalIgnoreCase) >= 0) {
                                search_path = names[i];
                                break;
                            }
                            Console.WriteLine(names[i]);
                        }
                        if (Directory.Exists(search_path))
                        {
                            var historyFiles = Directory.GetFiles(search_path, "*.txt")
                                                        .OrderByDescending(f => new FileInfo(f).LastWriteTime)
                                                        .ToList();

                            if (historyFiles.Count > 0)
                            {
                                Console.WriteLine($"\n「{search_path}」の検索履歴:");
                                for (int i = 0; i < historyFiles.Count; i++)
                                {
                                    Console.WriteLine($"  [{i}] {new FileInfo(historyFiles[i]).LastWriteTime}");
                                }
                                
                                string choiceStr = "0";
                                if (int.TryParse(choiceStr, out int choice) && choice >= 0 && choice < historyFiles.Count)
                                {
                                    files = File.ReadAllLines(historyFiles[choice]);
                                    mode = 1; // 検索後のモードに移行
                                    Console.WriteLine($"\n履歴を読み込みました ({files.Length}件)。準備ができました。");
                                }
                                else
                                {
                                    Console.WriteLine("無効な番号です。");
                                }
                            }
                            else
                            {
                                Console.WriteLine($"\n「{targetPath}」の履歴は見つかりませんでした。");
                            }
                        }
                        else
                        {
                            Console.WriteLine($"\n「{targetPath}」の履歴は見つかりませんでした。");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"\n履歴の読み込み中にエラーが発生しました: {ex.Message}");
                    }
                    continue;
                }
                
                
               
            }

            read_text = read_text.Trim('"');
            switch (mode)
            {
                case 0:
                    if (Directory.Exists(read_text))
                    {
                        string path = read_text;

                        Console.WriteLine("ファイルのリストを作成しています...");
                        List<string> fileList = new List<string>();
                        GetAllFilesRecursive(path, fileList);
                        files = fileList.ToArray();

                        // ===== ここから自動保存処理 =====
                        try
                        {
                            // 検索パスから履歴保存用のサブフォルダ名を生成
                            string targetDirName = Path.GetFileName(path);
                            if (targetDirName.Trim() == "") {
                                targetDirName = path;
                            }
                            


                            string saveDir = Path.Combine(historyBaseDir, SanitizePath(targetDirName));
                            Directory.CreateDirectory(saveDir);

                            // タイムスタンプ付きのファイル名を生成
                            string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                            string savePath = Path.Combine(saveDir, $"{timestamp}.txt");

                            File.WriteAllLines(savePath, files);
                            Console.WriteLine($"\nファイル一覧の履歴を保存しました: {savePath}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"\n履歴の保存中にエラーが発生しました: {ex.Message}");
                        }
                        // ===== ここまで自動保存処理 =====

                        Console.WriteLine("準備ができました");
                        mode = 1;
                    }
                    else
                    {
                        Console.WriteLine("フォルダがありません。フォルダを右クリックからパスをコピーを選択し、張り付けてください");
                    }
                    break;
                case 1:

                    if (read_text.Trim() == "") {
                        Console.WriteLine("入力が空です");
                        break;
                    }
                    // (case 1の検索表示処理は変更なし)
                    string z_path_ecoal = "";

                    var strList = new List<string>();
                    if (files.Length > 0)
                    {
                        for (int i = 0; i < files.Length; i++)
                        {
                            string file_name = Path.GetFileName(files[i]);
                            if (file_name.IndexOf(read_text, StringComparison.OrdinalIgnoreCase) >= 0)
                            {
                                string dir = "";
                                if (Directory.Exists(files[i])) {
                                    dir = files[i];
                                }
                                else { 
                                    dir = Path.GetDirectoryName(files[i]);
                                }
                                
                                if (dir != z_path_ecoal)
                                {
                                    z_path_ecoal = dir;

                                    strList.Add(i +"       "+ dir);
                                    Console.WriteLine($"\n{dir}\n");
                                }
                                Console.WriteLine($"   {i}   {file_name}");
                            }
                        }
                        Console.WriteLine("\n\n\n\n\n\n");

                        List<string> sortedAscending = strList.OrderBy(s => s.Length).ToList();
                        


                        foreach (string file_name in sortedAscending) { Console.WriteLine(file_name); }
                    }
                    break;
            }
        }

        
    }
 
}

Discussion