我想用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 );
这似乎是一个相当丑陋的黑客。有没有更好的办法?
当前回答
使用这个类。
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);
}
}
其他回答
只是想加上我的版本。它可以处理目录和文件,如果目标文件存在,则可以覆盖或跳过。
public static void Copy(
string source,
string destination,
string pattern = "*",
bool includeSubFolders = true,
bool overwrite = true,
bool overwriteOnlyIfSourceIsNewer = false)
{
if (File.Exists(source))
{
// Source is a file, copy and leave
CopyFile(source, destination);
return;
}
if (!Directory.Exists(source))
{
throw new DirectoryNotFoundException($"Source directory does not exists: `{source}`");
}
var files = Directory.GetFiles(
source,
pattern,
includeSubFolders ?
SearchOption.AllDirectories :
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
var newFile = file.Replace(source, destination);
CopyFile(file, newFile, overwrite, overwriteOnlyIfSourceIsNewer);
}
}
private static void CopyFile(
string source,
string destination,
bool overwrite = true,
bool overwriteIfSourceIsNewer = false)
{
if (!overwrite && File.Exists(destination))
{
return;
}
if (overwriteIfSourceIsNewer && File.Exists(destination))
{
var sourceLastModified = File.GetLastWriteTimeUtc(source);
var destinationLastModified = File.GetLastWriteTimeUtc(destination);
if (sourceLastModified <= destinationLastModified)
{
return;
}
CreateDirectory(destination);
File.Copy(source, destination, overwrite);
return;
}
CreateDirectory(destination);
File.Copy(source, destination, overwrite);
}
private static void CreateDirectory(string filePath)
{
var targetDirectory = Path.GetDirectoryName(filePath);
if (targetDirectory != null && !Directory.Exists(targetDirectory))
{
Directory.CreateDirectory(targetDirectory);
}
}
这是我的代码,希望对大家有所帮助
private void KCOPY(string source, string destination)
{
if (IsFile(source))
{
string target = Path.Combine(destination, Path.GetFileName(source));
File.Copy(source, target, true);
}
else
{
string fileName = Path.GetFileName(source);
string target = System.IO.Path.Combine(destination, fileName);
if (!System.IO.Directory.Exists(target))
{
System.IO.Directory.CreateDirectory(target);
}
List<string> files = GetAllFileAndFolder(source);
foreach (string file in files)
{
KCOPY(file, target);
}
}
}
private List<string> GetAllFileAndFolder(string path)
{
List<string> allFile = new List<string>();
foreach (string dir in Directory.GetDirectories(path))
{
allFile.Add(dir);
}
foreach (string file in Directory.GetFiles(path))
{
allFile.Add(file);
}
return allFile;
}
private bool IsFile(string path)
{
if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
{
return false;
}
return true;
}
复制并替换文件夹中的所有文件
public static void CopyAndReplaceAll(string SourcePath, string DestinationPath, string backupPath)
{
foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory($"{DestinationPath}{dirPath.Remove(0, SourcePath.Length)}");
Directory.CreateDirectory($"{backupPath}{dirPath.Remove(0, SourcePath.Length)}");
}
foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
{
if (!File.Exists($"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"))
File.Copy(newPath, $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}");
else
File.Replace(newPath
, $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"
, $"{ backupPath}{newPath.Remove(0, SourcePath.Length)}", false);
}
}
这里有一个简洁而有效的解决方案:
namespace System.IO {
public static class ExtensionMethods {
public static void CopyTo(this DirectoryInfo srcPath, string destPath) {
Directory.CreateDirectory(destPath);
Parallel.ForEach(srcPath.GetDirectories("*", SearchOption.AllDirectories),
srcInfo => Directory.CreateDirectory($"{destPath}{srcInfo.FullName[srcPath.FullName.Length..]}"));
Parallel.ForEach(srcPath.GetFiles("*", SearchOption.AllDirectories),
srcInfo => File.Copy(srcInfo.FullName, $"{destPath}{srcInfo.FullName[srcPath.FullName.Length..]}", true));
});
}
}
}
使用方法:
new DirectoryInfo(sourcePath).CopyTo(destinationPath);
或者,如果你想走一条艰难的路,为你的微软项目添加一个引用。然后使用下面的代码:
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(fromDirectory, toDirectory);
然而,使用一个递归函数是一个更好的方法,因为它不需要加载VB dll。