我有很多文件夹,每个文件夹超过500,000个。我想将它们分解为10,000(或50,000或5,000或用户定义的任何文件夹)的文件夹。
我的逻辑显然有问题,因为目前它只是将我的所有文件移动到它创建的第一个文件夹中。我尝试过使用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++;
}
}
}
答案 0 :(得分: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 :(得分: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);
}
在这种情况下,连续文件将放在不同的文件夹中。我不知道你的情况是否重要。
答案 2 :(得分:1)
您遇到的问题是以下代码永远不会跳出while循环,直到所有文件都移到您的文件夹1:
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;
}
答案 3 :(得分: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;