2014-09-23 33 views
0

我有一個做我的頭一個問題。C#如何通過文件系統重複和分配編號

我想通過在本地電腦的文件夾,包括目錄遍歷,並計算出一個編號系統對每個文件夾在文件系統層次結構中。

根文件夾應計算爲1,2,3等

如果有三個子文件夾在文件夾中的一個計算的數應該是: 1.1,1.2,1.3

如果有如果在文件夾2(根文件夾)中存在三個子文件夾,則計算出的數字應該爲: 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); 
     } 
    } 

希望這是顯而易見的。

感謝 裏克

+1

你的意思是你想提取出現在每個文件夾中的數字?您還應該顯示您在解決問題時所做的任何以前的嘗試 – Sayse 2014-09-23 07:31:29

+0

目錄或文件是否始終以數字結尾?如果沒有? – 2014-09-23 07:37:36

+0

我的理解是否正確,你知道如何去瀏覽目錄......但是有麻煩把那個數字放在那裏? (如果您還將用於追溯的代碼發佈到您的問題中,那將會很好)。 @TimSchmelter從我的理解Folder1,Folder2,...僅僅是examplenames,文件夾名稱/文件名中的數字只是巧合,並且與他想要做的編號無關 – Thomas 2014-09-23 07:43:14

回答

0

所以你要找到一個文件,並把它就是它的數量在目錄和它的所有父目錄?由於我發現它很有趣,我從頭開始寫了一些東西。需要注意的是,目前不能測試,但它可能反正給你一個想法:

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").ToList(); 
if(allEntriesFound.Any()) 
{ 
    foreach (FileEntryInfo entry in allEntriesFound) 
     Console.WriteLine("{0}: Number: {1}", entry.Path, entry.Number); 
    // here your exact requirement: 
    string result = string.Join(".", allEntriesFound[0].GetNumberTree()); 
    Console.WriteLine(result); 
} 

新增也是一種方式來指定的根目錄,以防止整個文件系統被搜索,用法:

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

感謝蒂姆,但我不想找到一個特定的文件只是分配一個數字到文件夾層次結構,然後我會寫入一個文件。一旦目錄編號計算得到解決,我也會將其擴展到文件。 – rick450d 2014-09-25 22:25:25

相關問題