Question GetDirectories Sort by Filename

dv2020

Active member
Joined
Dec 18, 2020
Messages
30
Programming Experience
1-3
Hi All

I'm using Directory.GetFiles to get a list of files, and populate the datagrid. Code is below. Everything is working, but I'm having trouble trying to get Directory.GetFiles to retrieve the list in filename or descending.

How anyone any idea if its possible, and if not via Directory.GetFiles, how to get the Datagrid to auto sort when its loaded with the list?

Current Code:
private void DataGridReports(string searchTxt)
        {
            DgReportList.DataSource = null;

            String[] files = Directory.GetFiles(reportDirPath, "*" + searchTxt + "*", SearchOption.AllDirectories);

            DataTable DGRptTable = new DataTable();
            DGRptTable.Columns.Add("ID");
            DGRptTable.Columns.Add("RPT");
            DGRptTable.Columns.Add("EXT");

            for (int i = 0; i < files.Length; i++)
            {
              
                FileInfo file = new FileInfo(files[i]);
                string rptid = string.Concat(file.Name.TakeWhile((c) => c != '.'));
                string rptext = file.Extension;
                string rptname = file.Name.Replace(rptid, "").Replace(rptext, "").Replace(".", "");

                DGRptTable.Rows.Add(rptid, rptname, rptext);
            }

Thank you

Dv
 
Solution
You can simplify some of that code by using an enumerator instead of taking the results into an array to then iterate over. Just enumerate the files as you access them :
C#:
            IEnumerator<string> files = Directory.EnumerateFiles(@"C:\Python38", "*", SearchOption.AllDirectories).GetEnumerator();
            while (files.MoveNext())
            {
                FileInfo file = new FileInfo(files.Current);
            }
Just change the the directory back to what you had set it before. I left the Python directory in there as that's the directory i used for testing it. You'd do better to build up paths using Path.Combine, and also without the overhead of using fileinfo which is probably not relevant for what you...
You can use the Sort method where you give column to sort and direction: DataGridView.Sort Method (System.Windows.Forms)

It is also possible to sort an array, but you should then first get an array of only filenames or FileInfo objects. First can be done with DirectoryInfo.GetFiles, second with Directory.GetFiles and Path.GetFilename.
 
If you already have paths as strings, I highly encourage using the various Path methods to parse the path rather than instantiating a FileInfo. The first time you access a property or method on a FileInfo instance, the framework will make an OS call to get all the information related to that object. OS calls are expensive because the framework has to cross the managed/unmanaged border to make the OS call, and then back again deliver the results of the OS call. If you parse the strings, everything stays on the managed side of the world.
 
Last edited:
You can simplify some of that code by using an enumerator instead of taking the results into an array to then iterate over. Just enumerate the files as you access them :
C#:
            IEnumerator<string> files = Directory.EnumerateFiles(@"C:\Python38", "*", SearchOption.AllDirectories).GetEnumerator();
            while (files.MoveNext())
            {
                FileInfo file = new FileInfo(files.Current);
            }
Just change the the directory back to what you had set it before. I left the Python directory in there as that's the directory i used for testing it. You'd do better to build up paths using Path.Combine, and also without the overhead of using fileinfo which is probably not relevant for what you need, unless you plan on accessing specific attributes of each file, in which case and by all means use it. By applying the advice by Skydiver, you could do something like this with the IEnumerator<string> of files :
C#:
            while (files.MoveNext())
            {
                var fileName = Path.GetFileNameWithoutExtension(files.Current);
                var fileExt = Path.GetExtension(files.Current);
                var dirOfFile = Path.GetDirectoryName(files.Current);
                if (dirOfFile.EndsWith("Python38"))
                {
                    string newfullPath = Path.Combine(dirOfFile, string.Concat(fileName, fileExt));
                    Console.WriteLine("Path : ", newfullPath);
                }
            }
This is just to give you an example of path building using Path. As you can see, this is much more specific, and way more usable resource wise as you are only using what you need by only using Path from the System.IO namespace.

I wouldn't use a file info object unless it is necessary to access a verity of other attributes of a given file not provided by the System.IO namespace/for Path. You will need to add back in your replace method calls. Since I don't know what you're trying to do there, and I didn't add that back in.

Stupidly you can't currently call for DirectoryInfo.GetFiles ToList, but this was said to be changed in the future. If you want to go this route, you can simply add a cast to the AddRange method :
C#:
            List<string> l = new List<string>();
            l.AddRange((IEnumerable<string>)files);

But if you want to sort files in code rather than on the controls as mentioned above, you will need to add a List<string> and add each file enumerated to it. This will allow you to call Sort on your list object. And you can also call OrderByDescending from Enumerable objects such as lists. If you want the last item in to be the first item to come out. Consider using a Stack<T>. Search up the highlighted words on MSDN. Hopefully this is helpful info to you!
 
Last edited:
Solution
Back
Top Bottom