我想用c#将一个目录的全部内容从一个位置复制到另一个位置。
使用System似乎没有办法做到这一点。没有大量递归的IO类。
如果我们添加对Microsoft的引用,VB中有一个方法可以使用。VisualBasic:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
这似乎是一个相当丑陋的黑客。有没有更好的办法?
我想用c#将一个目录的全部内容从一个位置复制到另一个位置。
使用System似乎没有办法做到这一点。没有大量递归的IO类。
如果我们添加对Microsoft的引用,VB中有一个方法可以使用。VisualBasic:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
这似乎是一个相当丑陋的黑客。有没有更好的办法?
当前回答
你可以一直使用这个,摘自微软网站。
static void Main()
{
// Copy from the current directory, include subdirectories.
DirectoryCopy(".", @".\temp", true);
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
其他回答
我的解决方案基本上是对@Termininja的答案的修改,但我增强了一点,它似乎比公认的答案快5倍以上。
public static void CopyEntireDirectory(string path, string newPath)
{
Parallel.ForEach(Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories)
,(fileName) =>
{
string output = Regex.Replace(fileName, "^" + Regex.Escape(path), newPath);
if (File.Exists(fileName))
{
Directory.CreateDirectory(Path.GetDirectoryName(output));
File.Copy(fileName, output, true);
}
else
Directory.CreateDirectory(output);
});
}
编辑:将@Ahmed Sabry修改为完全并行foreach确实会产生更好的结果,但是代码使用递归函数,在某些情况下并不理想。
public static void CopyEntireDirectory(DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)
{
if (!source.Exists) return;
if (!target.Exists) target.Create();
Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) =>
CopyEntireDirectory(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));
Parallel.ForEach(source.GetFiles(), sourceFile =>
sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles));
}
使用这个类。
public static class Extensions
{
public static void CopyTo(this DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)
{
if (!source.Exists) return;
if (!target.Exists) target.Create();
Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) =>
CopyTo(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));
foreach (var sourceFile in source.GetFiles())
sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles);
}
public static void CopyTo(this DirectoryInfo source, string target, bool overwiteFiles = true)
{
CopyTo(source, new DirectoryInfo(target), overwiteFiles);
}
}
比任何代码都好(使用递归扩展DirectoryInfo的方法)
public static bool CopyTo(this DirectoryInfo source, string destination)
{
try
{
foreach (string dirPath in Directory.GetDirectories(source.FullName))
{
var newDirPath = dirPath.Replace(source.FullName, destination);
Directory.CreateDirectory(newDirPath);
new DirectoryInfo(dirPath).CopyTo(newDirPath);
}
//Copy all the files & Replaces any files with the same name
foreach (string filePath in Directory.GetFiles(source.FullName))
{
File.Copy(filePath, filePath.Replace(source.FullName,destination), true);
}
return true;
}
catch (IOException exp)
{
return false;
}
}
抱歉之前的代码,它仍然有bug:((成为最快枪问题的猎物)。这里是测试和工作。键是SearchOption。AllDirectories,这消除了显式递归的需要。
string path = "C:\\a";
string[] dirs = Directory.GetDirectories(path, "*.*", SearchOption.AllDirectories);
string newpath = "C:\\x";
try
{
Directory.CreateDirectory(newpath);
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
for (int j = 0; j < dirs.Length; j++)
{
try
{
Directory.CreateDirectory(dirs[j].Replace(path, newpath));
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
}
string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
for (int j = 0; j < files.Length; j++)
{
try
{
File.Copy(files[j], files[j].Replace(path, newpath));
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
}
下面的代码是微软建议如何复制目录 由亲爱的@iato分享 但是它只是递归地复制源文件夹的子目录和文件,而不复制源文件夹本身(如右键单击->复制)。
但在这个答案下面有一个棘手的方法:
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs = true)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
如果你想递归复制源文件夹和子文件夹的内容,你可以像这样简单地使用它:
string source = @"J:\source\";
string dest= @"J:\destination\";
DirectoryCopy(source, dest);
但是如果你想复制源目录自己(类似于你右键单击源文件夹,然后单击复制,然后在目标文件夹中单击粘贴),你应该像这样使用:
string source = @"J:\source\";
string dest= @"J:\destination\";
DirectoryCopy(source, Path.Combine(dest, new DirectoryInfo(source).Name));