2010-12-07 141 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; 
相关问题