C# 递归?或者,如何让父母继续为人父母?
我之前发布过这篇文章,但不得不删除这个问题,因为我解释得太可怕了,对不起那些以前可能读过的人。让我更清楚一点。我必须创建一个winform应用程序,通过指定三项内容,允许用户将文件从一个目录复制到另一个目录:C# 递归?或者,如何让父母继续为人父母?,c#,winforms,recursion,C#,Winforms,Recursion,我之前发布过这篇文章,但不得不删除这个问题,因为我解释得太可怕了,对不起那些以前可能读过的人。让我更清楚一点。我必须创建一个winform应用程序,通过指定三项内容,允许用户将文件从一个目录复制到另一个目录: 从何处复制(txtPath) 要复制的文件扩展名是什么(您指定的是要复制的文件扩展名)(txtExtensions) 在哪里复制到(txtArchiveTo) 从视觉上看,它是这样的: c:\backup | -\temp | -drivers.exe
(txtPath)
(txtExtensions)
(txtArchiveTo)
c:\backup
|
-\temp
|
-drivers.exe (file)
-log.txt (file)
-\Test1 (directory)
-\Test2 (directory)
private void WalkDirectoryTree(DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
string[] extArray = txtExtensions.Text.Split(' '); //to hold the txtExtensions as an array string { "txt" "tar" "zip" etc.. }
string ext; //to hold the extension
// First, process all the files directly under this folder
try
{
files = root.GetFiles("*.*");
}
catch (UnauthorizedAccessException e)
{
throw; //todo: log this later on...
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
string extension = fi.Extension.ToString();
if (extension.IndexOf(".") > -1)
ext = extension.Substring(1, extension.Length-1);
else
ext = extension;
if (extArray.Any(s => ext.Contains(s)))
{
//copy the file
if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
{
//directory exists copy the files
}
else
{
Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
}
File.Copy(fi.FullName, txtArchiveTo.Text + "\\" + fi.Directory.Name + "\\" + fi.Name);
//create a shortcut pointing back to the file...
using (ShellLink shortcut = new ShellLink())
{
shortcut.Target = fi.FullName;
//shortcut.Description = "MY SHORTCUT";
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
shortcut.ShortCutFile = fi.DirectoryName + "\\" + fi.Name + ".lnk";
shortcut.Save();
}
}
}
// Now find all the subdirectories under this directory.
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}
从txtPath到TXTACHIVOVE的副本必须匹配其复制方式。也就是说,如果txtPath
如下所示:
c:\temp
|
-drivers.exe (file)
-log.txt (file)
-\Test1 (directory)
-\Test2 (directory)
然后,如果我为txtarchivevot
选择一个文件夹,例如c:\backup
,结果应该是在我的程序运行后,它应该是这样的:
c:\backup
|
-\temp
|
-drivers.exe (file)
-log.txt (file)
-\Test1 (directory)
-\Test2 (directory)
private void WalkDirectoryTree(DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
string[] extArray = txtExtensions.Text.Split(' '); //to hold the txtExtensions as an array string { "txt" "tar" "zip" etc.. }
string ext; //to hold the extension
// First, process all the files directly under this folder
try
{
files = root.GetFiles("*.*");
}
catch (UnauthorizedAccessException e)
{
throw; //todo: log this later on...
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
string extension = fi.Extension.ToString();
if (extension.IndexOf(".") > -1)
ext = extension.Substring(1, extension.Length-1);
else
ext = extension;
if (extArray.Any(s => ext.Contains(s)))
{
//copy the file
if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
{
//directory exists copy the files
}
else
{
Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
}
File.Copy(fi.FullName, txtArchiveTo.Text + "\\" + fi.Directory.Name + "\\" + fi.Name);
//create a shortcut pointing back to the file...
using (ShellLink shortcut = new ShellLink())
{
shortcut.Target = fi.FullName;
//shortcut.Description = "MY SHORTCUT";
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
shortcut.ShortCutFile = fi.DirectoryName + "\\" + fi.Name + ".lnk";
shortcut.Save();
}
}
}
// Now find all the subdirectories under this directory.
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}
这就是复制的内容需要遵循相同的结构…但我很难对其进行编码,因为它看起来好像我一直在引用root.Parent.Parent
,等等。让我发布一些代码:
Go
按钮非常基本:
private void btnGo_Click(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo(txtPath.Text);
WalkDirectoryTree(di);
}
这只是创建了一个directoryinfo对象,这样我就有了txtPath
目录的句柄,并调用了一个函数WalkDirectoryTree
。该函数如下所示:
c:\backup
|
-\temp
|
-drivers.exe (file)
-log.txt (file)
-\Test1 (directory)
-\Test2 (directory)
private void WalkDirectoryTree(DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
string[] extArray = txtExtensions.Text.Split(' '); //to hold the txtExtensions as an array string { "txt" "tar" "zip" etc.. }
string ext; //to hold the extension
// First, process all the files directly under this folder
try
{
files = root.GetFiles("*.*");
}
catch (UnauthorizedAccessException e)
{
throw; //todo: log this later on...
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
string extension = fi.Extension.ToString();
if (extension.IndexOf(".") > -1)
ext = extension.Substring(1, extension.Length-1);
else
ext = extension;
if (extArray.Any(s => ext.Contains(s)))
{
//copy the file
if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
{
//directory exists copy the files
}
else
{
Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
}
File.Copy(fi.FullName, txtArchiveTo.Text + "\\" + fi.Directory.Name + "\\" + fi.Name);
//create a shortcut pointing back to the file...
using (ShellLink shortcut = new ShellLink())
{
shortcut.Target = fi.FullName;
//shortcut.Description = "MY SHORTCUT";
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
shortcut.ShortCutFile = fi.DirectoryName + "\\" + fi.Name + ".lnk";
shortcut.Save();
}
}
}
// Now find all the subdirectories under this directory.
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}
请不要太注意我创建快捷方式的代码等。这部分不是问题所在。我遇到的困难是当我遇到以下代码行时:
if (extArray.Any(s => ext.Contains(s)))
{
//copy the file
if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
{
//directory exists copy the files
}
else
{
Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
}
if
只需检查文件的扩展名是否与用户在txtExtensions
中键入的扩展名匹配,这确保我们只复制具有这些扩展名的文件,而是在找到它们的文件夹中。我的问题就在那之后,如果……我不能说:
Directory.CreateDirectory(txtarchive.Text+“\\”+fi.Directory.Name)代码>
原因是存档文件夹必须与要复制的文件夹路径匹配。例如,如果有人选择c:\temp来搜索和查找要复制的txt文件,并且他们选择了一个文件夹c:\backup来复制,并且c:\temp有3个子文件夹(一个、两个和三个),其中也包含文本文件。结果是,在我的程序运行(完成“Go”)后,归档文件夹c:\backup将包含文件夹(一个、两个和三个),其中包含txt文件,此外还有c:\backup\One\mytest.txt等
我想在我当前的代码中加入这一点,我觉得我真的很接近,但我认为我需要进行一些重复以获得正确的目录结构。关于如何使用Directory.CreateDirectory或FileInfo类,请不要向我发送有关MSDN的链接,我已经阅读并理解了这些链接。将目标文件夹作为参数传递给您的步行功能:
private void WalkDirectoryTree(DirectoryInfo root, string DestinationFolder)
然后,复制文件时,只需使用fileInfo的CopyTo方法即可:
fi.CopyTo(DestinationFolder)
递归调用下一个方法时,只需将以下内容添加到指定路径:
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo, System.IO.Path.Combine(DestinationFolder, dirInfo.Name));
}
进行初始调用时,需要计算输出目录:
string path = txtPath.Text;
string outputDir = txtArchiveTo.Text
string finalDir = System.IO.Path.Combine(outputDir, path.Remove(0, System.IO.Path.GetPathRoot(path).Length));
DirectoryInfo di = new DirectoryInfo(txtPath.Text);
WalkDirectoryTree(di, finalDir);
@这不是我的问题…我知道如何递归复制文件。问题是如何维护正确的路径,因为我第一次获取文件。然后,如果出现一个目录,它会调用WalkDirectoryTree,这就是它可以变得很奇怪的地方,因为该目录需要与txtPath处于同一级别…当前路径应该保存在一个变量中。。现在,如果您在当前目录中,那么您应该将基于该扩展名的文件保存到一个数组或列表中,并在该循环中的foreach循环中迭代该列表,然后执行复制操作。这有意义吗?ispiro-我的问题是如何执行复制操作…因为只要我找到一个新目录和“WalkDirectoryTree()”我有了一个新的根目录…基本上副本应该匹配,但进入一个新位置,查看我的现有代码,我可以在那里做些什么来修复它…发布运行目录的结果的字符串值。Exists(txtArchiveTo.Text+“\\”+fi.Directory.Name
使用一个小示例。这样我们就可以了解您的代码是如何工作的,然后发布您真正想要的内容。我应该指出,您的最后一个段落毫无意义。这种工作方式……但请将此结构c:\temp\test1
想象为txtPath。txtcarchive
包含c:\backup
,之后使用您的代码,结果是c:\backup\test1
,但它应该是c:\backup\temp\test1
@oJM86o,然后指定c:\backup\temp作为初始调用的根目录WalkDirectoryTree@JohnKoerner我理解,但用户会选择说只是c:\backup。他或她永远不会记得输入c:\backup\temp。难道没有自动为其提供第一个遇到的文件夹的方法。Temp只是一个示例,它会改变…@oJM86o您必须决定规则。我不知道您的要求。如果用户选择了c:\Program Files\SomeApp,那么输出应该是c:\backup\SomeApp还是c:\backup\Program Files\SomeApp?我正在演示复制文件的修复方法您遇到的问题,我没有试图为您提供完整的解决方案。在这种情况下,可能是c:\backup\Program Files\SomeApp
这就是我的问题所在。