嘿,伙计们,我正试图将一个目录中的所有内容复制到另一个
示例文件夹:
//sourceFolder
//├File1.txt
//├Subfolder1
//| └File2.txt
//|
//└Subfolder2
// └File3.txt
//targetFolder
//├File1.txt
//├Subfolder1
//| └File2.txt
//|
//└Subfolder2
// └File3.txt
So far So good:
void Copy(string sourcePath, string targetPath)
{
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
string newPath;
foreach (string srcPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
{
newPath = srcPath.Replace(sourcePath, targetPath);
File.Copy(srcPath, newPath, true);
}
}
实际上我复制的是另一个目录下的所有内容
但是我试着进入目标文件夹:
//targetFolder
//├aFile1.txt
//├Subfolder1_aFile3.txt
//└Subfolder2_aFile4.txt
最后一个问题:
如何在文件名前面添加子文件夹名称
您应该使用Path
-class,在那里您可以找到必要的方法:
public static void Copy(string sourcePath, string targetPath, MergeDirectoryNameOption option = MergeDirectoryNameOption.MergeDirAndFile, string mergeDelimiter = "_")
{
var files = Directory.EnumerateFiles(sourcePath, "*.*", SearchOption.AllDirectories)
.Where(filePath => !IsFileInSubDirectoryOf(filePath, targetPath));
foreach (string srcPath in files)
{
string newFilePath = null;
switch (option)
{
case MergeDirectoryNameOption.MergeNon:
newFilePath = Path.GetFileName(srcPath);
break;
case MergeDirectoryNameOption.MergeAllButRoot:
string[] allDirs = srcPath.Split(Path.DirectorySeparatorChar);
newFilePath = string.Join(mergeDelimiter, allDirs.Skip(1));
break;
case MergeDirectoryNameOption.MergeDirAndFile:
string[] allDirsButLast = Path.GetDirectoryName(srcPath).Split(Path.DirectorySeparatorChar);
newFilePath = string.Join(Path.DirectorySeparatorChar.ToString(), allDirsButLast.Skip(1));
newFilePath = newFilePath + mergeDelimiter + Path.GetFileName(srcPath);
break;
default:
throw new NotSupportedException(string.Format("MergeDirectoryNameOption '{0}' is not supported.", option));
}
string newPath = Path.Combine(targetPath, newFilePath);
Directory.CreateDirectory(Path.GetDirectoryName(newPath));
File.Copy(srcPath, newPath, true);
}
}
相关部分为(Skip(1)
略过根):
string[] allDirsButLast = Path.GetDirectoryName(srcPath).Split(Path.DirectorySeparatorChar);
newFilePath = string.Join(Path.DirectorySeparatorChar.ToString(), allDirsButLast.Skip(1));
newFilePath = newFilePath + mergeDelimiter + Path.GetFileName(srcPath);
如果目标路径是源路径的子文件夹,则需要IsFileInSubDirectoryOf
-方法来避免有无限个子目录。MergeDirectoryNameOption
枚举只是额外的,您需要MergeDirAndFile
。
public enum MergeDirectoryNameOption
{
MergeNon = 0,
MergeAllButRoot = 1,
MergeDirAndFile = 2
}
public static bool IsFileInSubDirectoryOf(string filePath, string directory)
{
var dir1 = new DirectoryInfo(directory);
if (!dir1.Exists || !File.Exists(filePath))
return false;
var dir2 = new DirectoryInfo(Path.GetDirectoryName(filePath));
if (dir2.FullName == dir1.FullName) return true;
while (dir2.Parent != null)
{
if (dir2.Parent.FullName == dir1.FullName)
return true;
else
dir2 = dir2.Parent;
}
return false;
}