首页 > 解决方案 > 为同一行文本C#读取不同子文件夹中的特定文件

问题描述

我目前正在创建一个简短的控制台应用程序来读取多个子文件夹中的特定文件。该文件在所有目录中都具有相同的名称,因此将它们全部移动到一个目录并重命名它们将是一个巨大的麻烦(这些文件中有超过 365 个。它们每天都会自动创建一个新名称,并返回一些年)。但是,它们都在同一个主文件夹下。

我已经查看了读取目录子文件夹中的所有文件。我知道我能够搜索每个单独的子文件夹并查看所有文件(我能够将它们显示到控制台中,以便在我的声明中fileName找到每个文件。foreach

到目前为止的代码:

static void Main(string[] args)
{
    string readLine = string.Empty;
    var dir = new DirectoryInfo(@"C:\MotherDir\");
    // foreach loop to go through each subfolder to find FileINeed.txt
    foreach (var file in dir.EnumerateFiles("FileINeed.txt", SearchOption.AllDirectories))
    {
        //I get an error here: "System.IO.FileNotFoundException: 'Could not file file-'"
        using (StreamReader sr = new StreamReader(file.ToString()))   //this is using the wrong directory, not the one set previously (var dir)
        {
            while (!sr.EndOfStream)
            {
                readLine = sr.ReadLine();

                ProcessFiles(file.ToString());
            }
        }
    }

    Console.WriteLine("Finished.");
    Console.ReadKey(); //Gets pause at the end of the program
}

// Method to pass files through in order to search for specific string
static fileEntry ProcessFiles(string fileName)
{
    fileEntry inputFiles = new fileEntry();

    string fileString = string.Empty;
    string readLine;
    using (StreamReader sr = new StreamReader(fileName))
    {
        while (!sr.EndOfStream)
        {
            readLine = sr.ReadLine();

            if (readLine.Length < 1)
            {
            }

            if (readLine.Contains("RUN DATE: "))
            {
                Console.Write("RUN DATE:    ");
                Console.WriteLine(readLine);
            }
            if (readLine.Contains("1234567"))
            {
                Console.Write("Found this:    ");
                Console.WriteLine(readLine);
            }
            if (readLine.Contains("7654321"))
            {
                Console.Write("Found this:    ");
                Console.WriteLine(readLine);
            }
            if (readLine.Contains("1346785"))
            {
                Console.Write("Found this:    ");
                Console.WriteLine(readLine);
            }
            if (readLine.Contains("2589632"))
            {
                Console.Write("Found this:    ");
                Console.WriteLine(readLine);
            }
            if (readLine.Contains("12587412"))
            {
                Console.Write("Found this:    ");
                Console.WriteLine(readLine);
            }
        }
    }

    inputFiles.FileName = fileString;
    return inputFiles; 
}


public class fileEntry
{
    //stores file names and datetimes
    public string FileName { get; set; }

    public DateTime FileDate { get; set; }
}

我为寻找特定字符串的糟糕语句道歉if,我试图使用 switch/case 语句但无法让它工作。

如果它找到其中一个字符串,我只需要将其输出到控制台窗口(我知道我正在尝试输出整个readLine)。该程序的目的是查看这些字符串是否存在于正在处理的文件中。

我对 C# 还是很陌生,这是我从头开始编写的第一个有价值的程序之一。所以我为我仍在学习的糟糕的编码实践(如果有的话)道歉!如果您有任何建议或帮助,将不胜感激!如果我需要澄清任何事情,请告诉我!

先感谢您!

标签: c#

解决方案


您在那里不必要地使用 StreamReader,您应该将它传递给您的 ProcessFiles (不是 file.ToString() 而是 file.FullName ,它是文件的全名和路径 - 其他是 FileInfo 对象):

// foreach loop to go through each subfolder to find FileINeed.txt
foreach (var file in dir.EnumerateFiles("FileINeed.txt", SearchOption.AllDirectories))
{
    //I get an error here: "System.IO.FileNotFoundException: 'Could not file file-'"
            ProcessFiles(file.FullName);
}

注意:难以理解 ProcessFiles 的用途。即:为什么在作为新类处理时返回文件?您已经将它们放在第一次获得列表的位置。

注意2:顺便说一句,使用 dir.EnumerateFiles 或 dir.GetFiles 是比使用 Directory.GetFiles 更好的选择,特别是如果您还想过滤其他文件属性,如(CreationDate、ModificationDate ...)。

另一个样本:

void Main()
{
    string[] searches = { "RUN DATE: ", "1234567", "7654321", "1346785", "2589632", "12587412"};

    var dir = new DirectoryInfo(@"C:\MotherDir\");
    var files = from fi in dir.GetFiles("FileINeed.txt", SearchOption.AllDirectories)
                let content = File.ReadAllText(fi.FullName)
                // sample filter
                // where fi.CreationTime >= DateTime.Now.AddDays(-3)
                where searches.Any(c => content.Contains(c))
                select fi;

    foreach (var file in files)
    {
        Console.WriteLine(file.FullName);
    }           
}

推荐阅读