【问题标题】:How to find specific files in certain directories?如何在某些目录中查找特定文件?
【发布时间】:2014-05-18 03:34:14
【问题描述】:

我一直纠结于如何验证目录是否存在以及如果存在则搜索特定文件。我进行了各种尝试,但到目前为止,我最大的障碍是通过访问修饰符维护安全性,同时保留我正在尝试完成的模块化特性。 以下代码的目标:

  • 获取用户的驱动器以搜索特定目录。
  • 搜索驱动器以找到用户的 Steam 目录。
  • 寻找各种可执行文件;在这种情况下,三个最新的上古卷轴游戏。
  • 一旦检测到并验证,执行各种操作(启动、检查问题等)

是的,我知道这些东西已经存在,但我只是想了解如何执行这种性质的任务。请随意就应该更改的内容提出建议和建设性的意见,所有其他内容将被忽略。

       private void button1_Click(object sender, EventArgs e)
       {
           string[] drives = Directory.GetLogicalDrives();
           foreach (string d in drives)
           {
               TW_Detection.IDetection.arLoop((File.Exists(d + sd + g)) ? MessageBox.Show(gn + " has been detected in " + d + sd + g).ToString() : MessageBox.Show("The game was not detected!").ToString());
           }
        }
     }
  }

下一段代码是我尝试以各种方式创建最短的方法来执行一系列自动目录搜索以查找可执行文件。

    #region initialDetection
    public class initialDetection
    {
        private string[] games = { "morrowind\\Morrowind.exe", "oblivion\\Oblivion.exe", "skyrim\\TESV.exe" };
        private string[] games_names = { "The Elder Scrolls III: Morrowind", "The Elder Scrolls IV: Oblivion", "The Elder Scrolls V: Skyrim" };
        private string[] steamDirectories = { "Program Files\\steam\\steamapps\\common", "Program Files (x86)\\steam\\steamapps\\common", "steam\\steamapps\\common" };
        private void arLoop()
        {
            for (int i = 0; i < 2; i++)
            {
               string g = games[i];
               string gn = games[i];
            }
            for (int i = 0; i < 2; i++)
            {
               string sd = steamDirectories[i];
            }
         }
      }
    #endregion

    #region initialDetection
    public class gameDetection : steamDetection
    {
        private string[] games = { "morrowind\\Morrowind.exe", "oblivion\\Oblivion.exe", "skyrim\\TESV.exe" };
        private string[] games_names = { "The Elder Scrolls III: Morrowind", "The Elder Scrolls IV: Oblivion", "The Elder Scrolls V: Skyrim" };
        public partial void arLoop()
        {
            for (int i = 0; i < 2; i++)
            {
               string g = games[i];
               string gn = games_names[i];
            }
        }
     }
    #endregion

    #region precompileDetection
    public class precompileDetection : gameDetection
    {
        static string completeDirectory()
        {
           arLoop();
        }
     }
    #endregion

    #region steamDetection
    public class steamDetection
    {
        private string[] steamDirectories = { "Program Files\\steam\\steamapps\\common\\", "Program Files (x86)\\steam\\steamapps\\common\\", "steam\\steamapps\\common\\" };
        public partial void arLoop()
        {
            for (int i = 0; i < 2; i++)
            {
               string sd = steamDirectories[i];
            }
        }
     }
    #endregion

    #region Detection Interface
    public interface IDetection
    {
        void arLoop();
    }
    #endregion
 }

是的,我意识到这段代码非常混乱,并且包含很多不必要的和损坏的解决方案,这是我的实验结果。问题在于能够使用检测结果显示在一个消息框中,告诉用户游戏没有被检测到,或者它已经检测到然后显示游戏的名称已经被检测到。

【问题讨论】:

  • 根据经验:您几乎从不想要“长版”。让您的问题简短、中肯,并包含所有(且仅)相关的代码/信息。
  • Stackoverflow 是一个问答网站,因此请编辑您的帖子以明确您的问题。
  • @JeroenVannevel sccee.org

标签: c# winforms oop


【解决方案1】:
private string[] games = { "Morrowind.exe", "Oblivion.exe", "TESV.exe" };

public void findGameDirectories(String startDir)
{

    var games = from filePath in Directory.EnumerateFiles(startDir, "*.exe", SearchOption.AllDirectory)
                let fileName = Path.FileName(filePath)
                where games.Contains(fileName, StringComparison.InvariantCultureIgnoreCase)
                select filePath;
}

【讨论】:

  • 这段代码我目前只遇到一个问题; link 即使尝试了建议的解决方案来解决错误,也会出现新的错误。
  • 去俱乐部...早上会整理出来
【解决方案2】:

您可以使用递归解决方案,如下所示。

    private string[] games = { "Morrowind.exe", "Oblivion.exe", "TESV.exe" };

    public void findGameDirectories(String startDir)
    {
        foreach (var file in Directory.GetFiles(startDir))
        {
            foreach (var gameFileName in games)
            {
                if (file.EndsWith(gameFileName))
                {
                    // You found the game
                }
            }
        }

        foreach (var dir in Directory.GetDirectories(startDir))
        {
            // Search the subdirectories
            findGameDirectories(dir);
        }
    }

这将从您选择的文件夹开始,并检查该文件夹中的所有文件。然后,它将遍历每个子目录,并检查子目录中的每个文件,依此类推,直到用完子目录。

一旦找到所有游戏,您可能想告诉循环停止,但我会留给您:)

编辑:

我刚刚发现 C# 有一个非常简洁的小方法来列出所有文件,包括子目录

    public void findGameDirectories(String startDir)
    {
        DirectoryInfo directory = new DirectoryInfo(startDir);

        foreach (var file in directory.GetFiles("*.exe", SearchOption.AllDirectories))
        {
            foreach (var gameFileName in games)
            {
                if (file.Name == (gameFileName))
                {
                    Console.WriteLine("You found " + game.DisplayName);
                }
            }
        }
    }

【讨论】:

  • 哈哈,真奇怪!我就是在那一秒发现的!我从来没有真正写过很多 C#(我主要写 Java),但我正要更新我的答案:)
  • 很公平......但这是在 Linq 中完成的 .net 查询。这也是 Windows,文件名比较需要StringComparison.InvariantCultureIgnoreCase。鉴于您是 Java 开发人员,这是一次不错的尝试。
  • 您还想使用EnumerateFiles 而不是GetFilesGetFiles 返回一个包含所有文件的数组。而EnumerateFiles 返回一个对象,每次调用Enumerator.Next 时都会产生一个新的匹配项。不同之处在于,一个评估是惰性的,从而减少了内存需求。 :P 再次...优化,您的代码确实可以编译并运行并给出正确的答案。
  • 谢谢,我会记住这一点(如果您从 C:\Program Files 开始,这将产生巨大的影响)。出于兴趣,AllDirectories 选项是否递归搜索?我很想知道它是否会导致堆栈溢出,就像使用像我这样的递归方法时的情况。
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多