读取同一行C#的不同子文件夹中的特定文件

时间:2018-08-21 14:14:19

标签: c#

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

我调查了Read all files in directory sub folders。我知道我能够搜索每个单独的子文件夹并查看所有文件(我能够显示其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#还是很陌生,这是我从头开始编写的第一个有价值的程序之一。因此,对于仍在学习中的不良编码做法(如果有),我深表歉意!如果您有任何建议或帮助,将不胜感激!请让我知道是否需要澄清!

提前谢谢!

4 个答案:

答案 0 :(得分:4)

您在那里不必要使用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:Bdir使用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);
    }           
}

答案 1 :(得分:2)

错误地跳出的原因是,您正在打开每个文件,并将文件内容传递给ProcessFiles,实际上它需要文件名而不是文件内容。尝试将main()方法更改为此...

static void Main(string[] args)
{
    // this gets all matching files in a string array...
    string[] allfiles = Directory.GetFiles(@"C:\MotherDir\", "FileINeed.txt", SearchOption.AllDirectories);

    // parse the string array and call ProcessFiles for each one...
    foreach (var file in allfiles)
    {
        ProcessFiles(file);
    }

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

答案 2 :(得分:0)

dir.EnumerateFiles返回一个FileInfo对象。使用file。FullName属性来获取标准路径名。

答案 3 :(得分:0)

我认为这是您的使用

file.ToString()

我不确定它返回什么。要从FileInfo获取流,您需要使用

file.OpenText()

所以失败的代码将是

using (StreamReader sr = file.OpenText())

您的ProcessFiles可以使用FileInfo而不是字符串,然后您就可以获取

static fileEntry ProcessFiles(FileInfo file)

如果您想从FileInfo获取文件的完整路径,则可以使用

Path.Combine(file.DirectoryName, file.Name)