2010-12-07 257 views
2

我有許多文件夾,每個文件夾中有超過500,000個項目。我想把它們分解成10000個文件夾(或50,000或5,000個文件夾或任何用戶定義的文件夾)。爲每個文件夾創建x個文件夾的文件夾結構

在我的邏輯中顯然存在一些問題,因爲它現在只是將所有文件移動到第一個文件夾中創建。我嘗試過使用不同的foreach和where組合,但沒有運氣。

 //Find all the files to move 
     string[] files = Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 
     //Use selects the number of files to go in each folder 
     long h = long.Parse(tbFilePerFolder.Text); 
     //Used later 
     long i = 0; 
     //Used later 
     long j = 0; 
     //Get the number of folders to create 
     long k = files.Count()/h; 

     //Report back the number of files found 
     lblFilesFound.Text = "Files Found: " + files.Count(); 

     //Create the necessary number of folders, plus 1 to pick up remainders 
     while (j <= k + 1) 
     { 
      Directory.CreateDirectory(textBox1.Text + @"\" + j.ToString("00000")); 
      lblFoldersCreated.Text = "Folders Created: " + j; 
      j++; 
     } 

     //Get each folder that's just been created 
     string[] folders = Directory.GetDirectories(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 

     //For each of those folders... 
     foreach (string folder in folders) 
     { 
      //While there is less than the requested number of folders... 
      while (i <= h) 
      { 
       //Get a list of the currently existing files 
       string[] files2 = Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 

       //And iterate through it, moving to the defined directory 
       foreach (string file in files2) 
       { 
        File.Move(file, folder + @"\" + Path.GetFileName(file)); 
        lblFilesMoved.Text = "Files Moved: " + i; 
        i++; 
       } 
      } 
     } 

回答

2

你最內層的循環也必須檢查i < h

foreach (string file in files2) 
{ 
    File.Move(file, folder + @"\" + Path.GetFileName(file)); 
    lblFilesMoved.Text = "Files Moved: " + i; 
    i++; 
    if (i > h) 
     break; 
} 

我也注意到你調用Directory.GetFiles()兩次,這是很昂貴的。
考慮重新使用第一個列表,並在移動後尋找新手。

如果你可以使用Fx4,那麼有Directory.EnumerateFiles()這可以使一個文件夾與500K文件相當不同。但是你必須更多地適應你的代碼。

1

你爲什麼不做某事喜歡:

int j=0; 
foreach (string filename in Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly) 
{ 
    File.Move(filename , Path.Combine(textBox1.Text + j.ToString("0000"), Path.GetFileName(file)); 
    j = (j + 1)%(k + 1); 
} 

在這種情況下,連續的文件將在不同的文件夾放。我不知道你的情況是否重要。

1

的問題,你有如下的代碼永遠不會跳出while循環,直到所有的文件移動到您的folder1:

while (i <= h) 
{ 
    string[] files2 = Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 
    foreach (string file in files2) 
    { 
     File.Move(file, folder + @"\" + Path.GetFileName(file)); 
     lblFilesMoved.Text = "Files Moved: " + i; 
     i++; //this will never jump out the while loop until all files moved to your folder1 
     } 
} 

相反,你應該使用下面的代碼:(儘量接近原來的代碼可能)

string[] files = Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 

    long h = long.Parse(tbFilePerFolder.Text); 
    long i = 0; 
    long j = 0; 
    long k = files.Count()/h; 
    lblFilesFound.Text = "Files Found: " + files.Count(); 
    while (j <= k + 1) 
      { 
       Directory.CreateDirectory(textBox1.Text + @"\" + j.ToString("00000")); 
       lblFoldersCreated.Text = "Folders Created: " + j; 
       j++; 
      } 

    string[] folders = Directory.GetDirectories(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly) 

    //do you really need to search again? or maybe you can just use files instead? 
    string[] files2 = Directory.GetFiles(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 


    ind d=0;     
    foreach (string file in files2) 
    { 
     string folder=folders[d]; 
     while (i <= h) 
     { 
      File.Move(file, folder + @"\" + Path.GetFileName(file)); 
      lblFilesMoved.Text = "Files Moved:" + i; 
      i++; 
     } 
     d++; 
     i=0; 

     } 
0

我結束了以上的一切,非常感謝這些想法! (也使用Directory.EnumerateFiles。)我意識到邏輯出錯的地方,並停止兩次調用GetFiles。

 string[] folders = Directory.GetDirectories(textBox1.Text, "*.*", SearchOption.TopDirectoryOnly); 

     long d = 0; 
     long c = 0; 
     //And iterate through it, moving to the defined directory 
     while (d <= k) 
     { 
      while (i <= h) 
      { 
       try 
       { 
        string folder = folders[d]; 
        string file = files[c]; 
        File.Move(file, folder + @"\" + Path.GetFileName(file)); 
        c++; 
        i++; 
        lblFilesMoved.Text = "Files Moved: " + i; 
       } 
       catch (Exception f) 
       { 
        MessageBox.Show(f.ToString()); 
       } 
      } 
      d++; 
      i = 0; 
相關問題