【问题标题】:DirectoryInfo output, directories missingDirectoryInfo 输出,缺少目录
【发布时间】:2014-03-18 16:32:26
【问题描述】:

我正在尝试使用DirectoryInfo.GetDirectories() 来查找给定路径下的每个目录。

问题是它似乎工作正常,当它尝试从System Volume Information 读取时,除了UnauthorizedAccess Exception 之外没有其他错误,但仍然在它丢失目录的最后。

根据 TotalCMD(使用属性选项)我的 D:\ Drive 有 4580 个目录,根据 Windows Explorer 它有 4574,根据我的程序它有 4566...

我已经尝试了我能想到的一切。一个一个检查DIR-s,清空回收站,包括手动隐藏目录,但似乎没有任何区别。而且这不仅仅是在我的 D 盘上......

这是一个常见的错误还是有原因?

(只是提到我完全是自学c#,所以我做事的方法可能完全错误,这只是我如何克服我还不知道的事情)

编辑:我的所有代码:

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());
            }

    }
}

【问题讨论】:

  • 你能显示你正在使用的代码吗?
  • @ChrisBallard 添加了我的代码的相关部分
  • 你能把所有的都贴出来吗?tempDirectoryInfo 之类的东西不见了,所以我真的找不到你的起点
  • @ChrisBallard 当然,很抱歉

标签: c# subdirectory directoryinfo


【解决方案1】:

我要开枪并假设您首先想要获取给定路径下所有目录的单个列表(递归)。这段代码应该这样做:

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

或者如果您需要基于模式的所有文件,请使用:

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

编辑:

如果您对UnauthorizedAccessException 有疑问,您可以使用 LINQ 和递归来滚动您自己的实现,例如:

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>();
    }
}

您可以调用(并返回数组),例如:

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

支持多个基本路径

如果您有一个包含多个基本路径的数组,我们可以再次使用SelectMany 将所有内容放在一个列表中,所以:

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

这意味着对于basePaths 中的每个项目,我们将使用该条目来选择许多匹配的项目(在本例中通过调用MyGetDirectories),然后将所有内容连接到一个大列表中。在最后一步中,它被转换回一个数组。

【讨论】:

  • 哇...如果递归搜索就这么简单,那么我可能只是在浪费时间重新发明轮子...我会试试这个!谢谢
  • .NET 有这么多的角落和缝隙 - 很容易错过这样的功能:)
  • 问题是,我正在尝试理解你的代码(它仍然有点超出我的头脑)但我有一组基本路径,问题是你的第一个解决方案有效很棒,但无法处理 UnauthorizedAccessException,第二个我无法使用多个基本路径
  • 抱歉,我使用了一些 LINQ 技巧!修改为包含多个基本目录的示例 - 如果有帮助,请告诉我
  • 感谢所有帮助!最后,由于这些原因,我发现使用我编写的代码更简单,但是感谢您的帮助,下次它可能会对我有很大帮助。我也想我知道出了什么问题。每次它访问一个目录时它都无法读取它跳过一大堆只是因为我如何编写我的代码......再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2017-04-25
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多