Gerald
Gerald

Reputation: 1083

Read a text from string then compare on list of xml files using c#

I have a console application which will read all the .txt and .xml files on a directory. Inside the txt file, are list of xml files. My application must read every txt file inside then check if the xml files listed inside the txt files are available on that directory.

Files inside the directory example:

123_Client_01022013_Summary.txt
123_Client_01022013_File1.xml
123_Client_01022013_File2.xml

Inside the 123_Client_01022013_Summary.txt is:

123_Client_01022013_File1.xml
123_Client_01022013_File2.xml

And this is my code:

var directorypath = @"C:\";
string line;

List<String> txtlist = Directory.GetFiles(directorypath, "*.txt").ToList();
List<String> xmllist = Directory.GetFiles(directorypath, "*.xml").ToList();

foreach (var txt in txtlist)
{
    StreamReader file = new StreamReader(txt);

    while ((line = file.ReadLine()) != null)
    {
        foreach (var xml in xmlist)
        {
            FileInfo fileinfo = new FileInfo(xml);

            if (fileinfo.Name == line)
            {
                break;
            }
        }
    }
}

This code is working: Checking the txt inside the txt file, then every line it will check if that xml is existing on the directory.

Is there any way I can do this a bit less expensive? I know my logic seems right but i'm not sure if this is the best way I can do it. Any advise would be appreciated. Thanks in advance!

Upvotes: 0

Views: 318

Answers (4)

Gerald
Gerald

Reputation: 1083

Upon considering one of the comments, I ended up not getting the list of xml files but the xml filenames only.

 List<String> txtlist = Directory.GetFiles(directorypath, "*.txt").ToList();
 List<String> xmllist = Directory.GetFiles(directorypath, "*.xml").Select(f => Path.GetFileName(f)).ToList();


 foreach (var txt in txtlist)
 {
     StreamReader file = new StreamReader(txt);

     while ((line = file.ReadLine()) != null)
     {
         foreach (var xml in xmlist)
         {
             if (xml == line)
             {
             break;
             }
         }
    }
 }

So now i'm not creating an object of FileInfo while doing a foreach loop.

Upvotes: 0

David Colwell
David Colwell

Reputation: 2590

Try something like this

        var directorypath = @"C:\";

        List<String> txtlist = Directory.GetFiles(directorypath, "*.txt").ToList();

        foreach (var textFile in txtlist)
        {
            using (StreamReader file = new StreamReader(textFile))
            {
                var xmlFiles = file.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                var xmlFilesThatDontExsit = xmlFiles.Where(x => !System.IO.File.Exists(x));
                //Do what you want with the files that dont exist
            }
        }

Of course this assumes that the only files in the Text file are XML files (as that is not checked)

Upvotes: 0

Thomas Levesque
Thomas Levesque

Reputation: 292475

Using Linq you can do something like that:

string[] txtList =
    Directory.EnumerateFiles(directorypath, "*.txt")
             .SelectMany(f => File.ReadAllLines(f))
             .ToArray();

string[] xmlList =
    Directory.EnumerateFiles(directorypath, "*.xml")
             .Select(f => Path.GetFileName(f))
             .ToArray();

// XML files that are listed in .txt files but are not present in the directory
var missingXmlFiles = txtList.Except(xmlList);

// XML files that are present in the directory but not listed in .txt files
var extraXmlFiles = xmlList.Except(txtList);

Upvotes: 2

Timoty Weis
Timoty Weis

Reputation: 170

Maybe you should read first just the txt files and get the list of valid xml files (so not create the xmllist at the beginning with the GetFiles), then separately open them. So you will not have the a O2 complexity (two nested foreach).

Upvotes: 1

Related Questions