c#如何迭代文件系统并分配编号

c#如何迭代文件系统并分配编号,c#,list,filesystems,C#,List,Filesystems,我有一个问题,这是我的头 我想遍历本地PC文件夹,包括目录,并计算文件系统层次结构中每个文件夹的编号系统 根文件夹应计算为1、2、3等 如果文件夹1中有三个子文件夹,则计算的数字应为: 1.1、1.2、1.3 如果上面的子文件夹中有三个子文件夹,则计算的数字应为: 1.1.1、1.1.2、1.1.3 如果文件夹2(根文件夹)中有三个子文件夹,则计算的数字应为: 2.1、2.2、2.3 或者用另一种方式表达: 1 Root Folder 1.1 Root Sub Folder 1

我有一个问题,这是我的头

我想遍历本地PC文件夹,包括目录,并计算文件系统层次结构中每个文件夹的编号系统

根文件夹应计算为1、2、3等

如果文件夹1中有三个子文件夹,则计算的数字应为: 1.1、1.2、1.3

如果上面的子文件夹中有三个子文件夹,则计算的数字应为: 1.1.1、1.1.2、1.1.3

如果文件夹2(根文件夹)中有三个子文件夹,则计算的数字应为: 2.1、2.2、2.3

或者用另一种方式表达:

 1   Root Folder 
 1.1   Root Sub Folder 1
 1.1.1   Sub Folder
 1.1.2     Sub Folder
 1.2 Root Sub Folder 2
 1.2.1 List item
 1.2.2   List item 
等等等等

然后,此逻辑应应用于所有文件夹和子文件夹

输出示例

1.1.1 | "c:\Root\Folder1\Folder1\"
到目前为止,我所做的在某些情况下似乎可以正常工作,但在其他情况下可能会失败:

    private string rootpath = @"C:\FolderHierarchy\";
    private string FolderSequenceCountBase = "";
    private int CurrentRootPathCount = 0;
    private int Counter = 0;

    private void CalculateFolderHierarchyNumbers()
    {
        //Get First List of Folders
        string[] Dirs = Directory.GetDirectories(rootpath, "*.*", SearchOption.TopDirectoryOnly);

        for (int i = 0; i < Dirs.Count(); i++)
        {
            FolderSequenceCountBase = (i + 1).ToString();
            CurrentRootPathCount = i + 1;
            Console.WriteLine("Processed folder '{0}'.", Dirs[i] + " = " + (i + 1));                
            GetSubDirs(Dirs[i]);
        }
    }

    private void GetSubDirs(string item)
    {
        //Get next list of folders in the folder hierarchy
        string[] SubDirs = Directory.GetDirectories(item, "*.*", SearchOption.TopDirectoryOnly);
        foreach (var DirPath in SubDirs)
        {
            //Increment count of folders within the current folder list
            Counter += 1;
            Console.WriteLine("Processed folder '{0}'.", DirPath + " = " + FolderSequenceCountBase + "." + Counter);
        }

        Counter = 0;

        //Get next list of folders in the folder hierarchy
        foreach (var DirPath in SubDirs)
        {
            FolderSequenceCountBase += ".1";
            GetSubDirs(DirPath);  
        }
    }
私有字符串根路径=@“C:\FolderHierarchy\”;
私有字符串FolderSequenceCountBase=“”;
private int CurrentRootPathCount=0;
专用整数计数器=0;
私有void CalculateFolderHierarchyNumbers()
{
//获取文件夹的第一个列表
字符串[]Dirs=Directory.GetDirectories(根路径,*.*,SearchOption.TopDirectoryOnly);
对于(int i=0;i
希望这是清楚的

谢谢
Rick

那么你想找到一个文件并得到它在of目录和所有父目录中的编号?自从我发现它很有趣,我就从头开始写了一些东西。请注意,它目前尚未测试,但它可能会给您一个想法:

public static IEnumerable<FileEntryInfo> EnumerateFindFiles(string fileToFind, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase, DirectoryInfo rootDir = null, string[] drivesToSearch = null)
{
    IEnumerable<FileEntryInfo> foundEntries = Enumerable.Empty<FileEntryInfo>();
    if (rootDir != null && drivesToSearch != null)
        throw new ArgumentException("Specify either the root-dir or the drives to search, not both");
    else if (rootDir != null)
    {
        foundEntries = EnumerateFindEntryRoot(fileToFind, rootDir, comparison);
    }
    else
    {
        if (drivesToSearch == null) // search the entire computer
            drivesToSearch = System.Environment.GetLogicalDrives();
        foreach (string dr in drivesToSearch)
        {
            System.IO.DriveInfo di = new System.IO.DriveInfo(dr);

            if (!di.IsReady)
            {
                Console.WriteLine("The drive {0} could not be read", di.Name);
                continue;
            }
            rootDir = di.RootDirectory;
            foundEntries = foundEntries.Concat(EnumerateFindEntryRoot(fileToFind, rootDir, comparison));
        }
    }
    foreach (FileEntryInfo entry in foundEntries)
        yield return entry;
}

public class FileEntryInfo
{
    public FileEntryInfo(string path, int number)
    {
        this.Path = path;
        this.Number = number;
    }
    public int Number { get; set; }
    public string Path { get; set; }
    public FileEntryInfo Root { get; set; }

    public IEnumerable<int> GetNumberTree()
    {
        Stack<FileEntryInfo> filo = new Stack<FileEntryInfo>();
        FileEntryInfo entry = this;
        while (entry.Root != null)
        {
            filo.Push(entry.Root);
            entry = entry.Root;
        }
        while(filo.Count > 0)
            yield return filo.Pop().Number;
        yield return this.Number; 
    }


    public override bool Equals(object obj)
    {
        FileEntryInfo fei = obj as FileEntryInfo;
        if(obj == null) return false;
        return Number == fei.Number && Path == fei.Path;
    }

    public override int GetHashCode()
    {
        return Path.GetHashCode();
    }

    public override string ToString()
    {
        return Path;
    }
}

private static IEnumerable<FileEntryInfo> EnumerateFindEntryRoot(string fileNameToFind, DirectoryInfo rootDir, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase)
{
    Queue<FileEntryInfo> queue = new Queue<FileEntryInfo>();
    FileEntryInfo root = new FileEntryInfo(rootDir.FullName, 1);
    queue.Enqueue(root);

    while (queue.Count > 0)
    {
        FileEntryInfo fe = queue.Dequeue();
        List<FileEntryInfo> validFiles = new List<FileEntryInfo>();
        try
        { // you cannot yield from try-catch, hence this approach
            FileAttributes attr = File.GetAttributes(fe.Path);
            //detect whether its a directory or file
            bool isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory;
            if (isDirectory)
            {
                int entryCount = 0;
                foreach (string entry in Directory.EnumerateFileSystemEntries(fe.Path))
                {
                    entryCount++;
                    FileEntryInfo subEntry = new FileEntryInfo(entry, entryCount);
                    subEntry.Root = fe;
                    queue.Enqueue(subEntry);
                    attr = File.GetAttributes(entry);
                    isDirectory = (attr & FileAttributes.Directory) == FileAttributes.Directory;
                    if(!isDirectory)
                        validFiles.Add(subEntry);
                }
            }

        } catch (Exception ex)
        {
            Console.Error.WriteLine(ex); // ignore, proceed
        }

        foreach (FileEntryInfo entry in validFiles)
        {
            string fileName = Path.GetFileName(entry.Path);
            if (fileName.Equals(fileNameToFind, comparison))
                yield return entry;
        }
    }
}
还添加了一种指定根目录以防止搜索整个文件系统的方法,用法:

var allEntriesFound = EnumerateFindFiles(
  "PresentationFramework.dll", 
  StringComparison.CurrentCultureIgnoreCase,
  new DirectoryInfo(@"C:\Windows"))
.ToList();

您的意思是希望提取每个文件夹中的数字吗?您还应该展示您以前在解决此问题时所做的任何尝试。目录或文件是否总是以数字结尾?如果没有呢?我理解正确吗?你知道如何浏览目录,。。。但是,在计算上有困难吗?(如果您也将用于遍历的代码发布到您的问题中,这将是一件好事)@TimSchmelter从我的理解来看Folder1,Folder2,。。。这些只是示例名称,foldernames/FileName中的数字只是巧合,与他想做的编号无关(但如果rick450d woiuld也清楚这一点或张贴(如果是这样或不是这样),以及是什么定义了特定文件夹/文件获得的编号[仅在内部目录或其他目录下排序]只需为“listfolder”和“listfiles”函数添加一个额外的字符串参数。-->doneThanks Tim,但我不想找到特定的文件,只需为文件夹层次结构分配一个编号,然后将其写入文件。解决目录编号计算后,我还会将此扩展到文件。
var allEntriesFound = EnumerateFindFiles(
  "PresentationFramework.dll", 
  StringComparison.CurrentCultureIgnoreCase,
  new DirectoryInfo(@"C:\Windows"))
.ToList();