如何在复制时在文件名前面添加子文件夹名

本文关键字:添加 文件夹 前面 文件名 复制 | 更新日期: 2023-09-27 18:19:21

嘿,伙计们,我正试图将一个目录中的所有内容复制到另一个

示例文件夹:

//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;
}