В настоящее время я создаю короткое консольное приложение для чтения определенного файла в нескольких подпапках. Файл имеет одинаковое имя во всех каталогах, поэтому перемещение их в один каталог и переименование их было бы огромной проблемой (существует более 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#
2
Symon 21 Авг 2018 в 17:14

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: Кстати, использование 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);
    }           
}
4
Cetin Basoz 21 Авг 2018 в 15:06

То, что выглядело неправильно, это то, что вы открываете каждый файл и передаете содержимое файла в 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
Reinstate Monica Cellio 21 Авг 2018 в 14:25

Я думаю, что это ваше использование

file.ToString()

Который я не уверен, что он возвращает. Чтобы получить поток из FileInfo вам нужно использовать

file.OpenText()

Так что ваш ошибочный код будет

using (StreamReader sr = file.OpenText())

И ваши ProcessFiles могут взять FileInfo вместо строки, и вы получите это

static fileEntry ProcessFiles(FileInfo file)

Если вы хотите получить полный путь к вашему файлу из FileInfo, вы можете использовать

Path.Combine(file.DirectoryName, file.Name)
0
Jihad Haddad 21 Авг 2018 в 14:29

dir.EnumerateFiles возвращает объект FileInfo. Используйте свойство file. FullName, чтобы получить полное имя пути.

0
Philip Smith 21 Авг 2018 в 14:21
51950688