Pregunta

I'm trying to use DirectoryInfo.GetDirectories() to look up every directory under a given path.

The problem is that it seems to work OK, there are no errors other then the UnauthorizedAccess Exception when it tries reading from System Volume Information but still at the end of all that it's missing directories.

According to TotalCMD (using the properties option) my D:\ Drive has 4580 directories, According to Windows Explorer it has 4574 and according to my program it has 4566...

I've tried everything i could think of. Checking the DIR-s one by one, emptying the recycle bin, including hidden directories manually, but nothing seems to make a difference. Also that'S not just on my D drive as well...

Is that a common bug or is there a reason?

(Just mentioning that I'm learning c# completely by myself so my methods for doing stuff are probably completely wrong, it's just how i get past the things i don't know yet)

EDIT: All my Code:

FindDirectories.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;


namespace WolfPaw_Duplicate_Search_and_Destroy
{
    class FindDirectories
    {
        DirectoryInfo[] tempDirectoryInfo;
        DirectoryInfo[] fullDirectoryInfo;
        String tmpDirInfo = "";
        String tmpDirInfo2 = "";
        String[] fullDirInfo = new String[1000000];
        DirectoryInfo[] dinf = new DirectoryInfo[100];

        public DirectoryInfo[] getDirectories(DirectoryInfo[] dinf)
        {
            tempDirectoryInfo = dinf;

            GetDirectories();

            return fullDirectoryInfo;
        }



        private void GetDirectories()
        {
            try
            {
                int index = 0;
                try
                {
                    foreach (DirectoryInfo dinf in tempDirectoryInfo)
                    {
                        if (dinf != null)
                            foreach (DirectoryInfo dd in dinf.GetDirectories())
                            {
                                if (dd != null)
                                {
                                    tmpDirInfo += dd.FullName + "♣";
                                    index++;
                                }
                            }
                    }
                }
                catch(Exception ex) { MessageBox.Show("Current working directories: " + tmpDirInfo + Environment.NewLine + "Error Message: " + ex.Message); }

                tmpDirInfo2 += tmpDirInfo;

                tempDirectoryInfo = new DirectoryInfo[index];

                index = 0;
                foreach (String s in tmpDirInfo.Split('♣'))
                {
                    if (s.Length > 0)
                        tempDirectoryInfo[index] = new DirectoryInfo(s);
                    index++;
                }

                tmpDirInfo = "";

                int i = 0;
                foreach (DirectoryInfo x in tempDirectoryInfo)
                {
                    if (x != null)
                        i++;
                }

                if (tempDirectoryInfo.Length != 0)
                {
                    GetDirectories();
                }
                else
                {
                    StringToDirInfo(tmpDirInfo2);
                }

            }
            catch (UnauthorizedAccessException)
            { }
            catch (Exception)
            {
                throw;
            }


        }

        private void StringToDirInfo(String s_dInfo)
        {
            int index = 0;

            foreach (String s in s_dInfo.Split('♣'))
            {
                index++;
            }

            fullDirectoryInfo = new DirectoryInfo[index];

            index = 0;
            foreach (String s in s_dInfo.Split('♣'))
            {
                if (s.Length > 0)
                {
                    fullDirectoryInfo[index] = new DirectoryInfo(s);
                    index++;
                }
            }

        }


    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WolfPaw_Duplicate_Search_and_Destroy
{
    public partial class Form1 : Form
    {
            public Form1()
            {
                    InitializeComponent();

                    foreach(String s in Environment.GetLogicalDrives())
                    {
                            DriveInfo dinf1 = new DriveInfo(s);

                            try
                            {
                                    if(dinf1.DriveType != DriveType.CDRom)
                                    {
                                            textBox_Dirs.Text += s + "||";
                                    }
                            }
                            catch { }
                    }

                    comboBox_Larger.SelectedIndex = 0;
                    comboBox_Smaller.SelectedIndex = 0;
            }

            private void button_DirResize_Click(object sender, EventArgs e)
            {
                    if (textBox_Dirs.Height < 100)
                    {
                            textBox_Dirs.Height = 100;
                            textBox_Dirs.Multiline = true;
                            button_DirResize.Top = textBox_Dirs.Bottom - (button_DirResize.Height / 2); 
                    }
                    else
                    {
                            textBox_Dirs.Height = 20;
                            textBox_Dirs.Multiline = false;
                            button_DirResize.Top = textBox_Dirs.Bottom - (button_DirResize.Height / 2); 
                    }

                    textBox_FileTypes.Top = textBox_Dirs.Bottom + 15;
                    comboBox_Filetypes.Top = textBox_FileTypes.Top;
                    label_FyleType.Top = textBox_FileTypes.Top + ((textBox_FileTypes.Height / 2) - (label_FyleType.Height / 2));
                    button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
            }

            private void comboBox_Filetypes_SelectedIndexChanged(object sender, EventArgs e)
            {
                    if (comboBox_Filetypes.SelectedItem.ToString().Contains("*.*") == false)
                    {
                            if (textBox_FileTypes.Text.Contains("*.*; "))
                            {
                                    textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*; ", "");
                            }
                            else if (textBox_FileTypes.Text.Contains("*.*;"))
                            {
                                    textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*;", "");
                            }
                            else if (textBox_FileTypes.Text.Contains("*.*"))
                            {
                                    textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("*.*", "");
                            }

                    }

                    textBox_FileTypes.Text += comboBox_Filetypes.SelectedItem.ToString().Substring(comboBox_Filetypes.SelectedItem.ToString().IndexOf("(") + 1).Replace(")","") + "; ";
            }

            private void textBox_FileTypes_TextChanged(object sender, EventArgs e)
            {
                    if(textBox_FileTypes.Text.Contains("*.*"))
                    {
                            textBox_FileTypes.Text = "*.*;";
                    }
                    else if(textBox_FileTypes.Text.Contains("; ; "))
                    {
                            textBox_FileTypes.Text = textBox_FileTypes.Text.Replace("; ; ","; ");
                    }
                    else if (textBox_FileTypes.Text.Contains(";; "))
                    {
                            textBox_FileTypes.Text = textBox_FileTypes.Text.Replace(";; ", "; ");
                            textBox_FileTypes.SelectionStart = textBox_FileTypes.Text.Length;
                            textBox_FileTypes.Select();
                    }
            }

            private void button_FileTypeResize_Click(object sender, EventArgs e)
            {
                    if (textBox_FileTypes.Height < 100)
                    {
                            textBox_FileTypes.Height = 100;
                            textBox_FileTypes.Multiline = true;
                            button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
                    }
                    else
                    {
                            textBox_FileTypes.Height = 20;
                            textBox_FileTypes.Multiline = false;
                            button_FileTypeResize.Top = textBox_FileTypes.Bottom - (button_FileTypeResize.Height / 2);
                            label_FyleType.Top = textBox_FileTypes.Top + ((textBox_FileTypes.Height / 2) - (label_FyleType.Height / 2));
                    }

                    textBox_FileTypes.Top = textBox_Dirs.Bottom + 15;
                    comboBox_Filetypes.Top = textBox_FileTypes.Top;

            }

            private void button1_Click(object sender, EventArgs e)
            {
                    if (label_FileBeingChecked.Height < 100)
                    {
                            label_FileBeingChecked.Height = 100;
                            button1.Text = "↑";
                            button1.Cursor = Cursors.PanNorth;
                    }
                    else
                    {
                            label_FileBeingChecked.Height = 24;
                            button1.Text = "↓";
                            button1.Cursor = Cursors.PanSouth;
                    }

                    progressBar1.Top = label_FileBeingChecked.Bottom + 2;
                    label_FNumber.Top = progressBar1.Bottom + 4;
                    label_NumOfFiles.Top = progressBar1.Bottom + 4;
            }

            private void button_Browse_Click(object sender, EventArgs e)
            {
                    FolderBrowserDialog ofd = new FolderBrowserDialog();
                    DialogResult dres = ofd.ShowDialog();

                    if(dres == System.Windows.Forms.DialogResult.OK)
                    {
                            textBox_Dirs.Text += ofd.SelectedPath + "||";
                    }
            }

            private void button_Start_Click(object sender, EventArgs e)
            {
                    StartSearch();
            }

            public void StartSearch()
            {
                    //Get Directory List

                    FindDirectories fd = new FindDirectories();

                    int index = 0;

                    String[] s_Dirs = textBox_Dirs.Text.Replace("||","↓").Split('↓');

                    DirectoryInfo[] di = new DirectoryInfo[s_Dirs.Length];

                    foreach(String s in s_Dirs)
                    {
                            if(s.Length != 0)
                            di[index] = new DirectoryInfo(s);
                            index++;
                    }

                    DirectoryInfo[] dinfo = fd.getDirectories(di);

                    int xx = 0;
                    String testStr = "";
                    foreach (DirectoryInfo d in dinfo)
                    {
                            if (d != null)
                            {
                                    //testStr += d.Root + "  |  " + d.Parent + "  |  " + d.FullName + "♣";
                                    xx++;
                            }
                    }
                    //testStr += "♣♣ # of Directories found:" + xx;
                    //File.WriteAllText(@"C:\t.txt",testStr.Replace("♣",Environment.NewLine));

                    MessageBox.Show(xx.ToString());
            }

    }
}
¿Fue útil?

Solución

I'm going to jump the gun and assume you firstly want to get a single list of all directories beneath a given path (recursively). This code should do that:

string[] allDirs = Directory.GetDirectories(@"D:\", "*.*", SearchOption.AllDirectories);

or if you need all files based on a pattern, just go with:

string[] allFiles = Directory.GetFiles(@"D:\", "*.*", SearchOption.AllDirectories);

EDIT:

If you have trouble with UnauthorizedAccessException, you can roll your own implementation using LINQ and recursion, such as:

private static IEnumerable<string> MyGetDirectories(string basePath)
{
    try
    {
        string[] dirs = Directory.GetDirectories(basePath);
        return dirs.Union(dirs.SelectMany(dir => MyGetDirectories(dir)));
    }
    catch(UnauthorizedAccessException)
    {
        return Enumerable.Empty<string>();
    }
}

Which you can call (and turn back to an array) with something like:

string[] allDirs = MyGetDirectories(@"D:\").ToArray();

Supporting Multiple Base Paths

If you have an array with multiple base paths, we can use SelectMany again to get everything in one list, so:

string[] basePaths = new string[] { @"C:\", @"D:\" };
string[] allDirs = basePaths.SelectMany(dir => MyGetDirectories(dir)).ToArray();

The meaning of this is that for each item in basePaths, we will use that entry to select many matching items (in this case by calling MyGetDirectories) and then everything is joined together into one big list. In the last step this is converted back into an array.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top