首页 > 解决方案 > 复制所有文件夹,除了 C# 中的某些文件夹和文件

问题描述

我想将所有文件夹和文件从“源”复制到“目标”,除了某个目录(systemdir)。

我参考的这个方法: C# Searching for files and folder except in certain folder

但我发现我的结果有一些问题:

源目录中如果有“Intel”或任何以“Intel”开头的文件夹,如“Intel123”,将一并排除。所以我希望将文件夹完全复制到我提到的文件夹中,而不是全部包含目录名称。

如果有其他方法,请随时分享。

以下是我的代码:

using System;
using System.IO;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string serialNum = "MS001";
            string userName = Environment.UserName;
            string sourcecpath = "C:\\Users\\" + userName + "\\Desktop\\Dummy\\Local C";
            string targetcpath = "C:\\Users\\" + userName + "\\Desktop\\Dummy\\Desktop\\" + serialNum + "\\Local C";
            copy(sourcecpath, targetcpath);
        }

    public static void copy(string source, string target)
    {

        string[] systemdir = new string[] {  "Error", "Intel", "PerfLogs", "Program Files", "Users", "Windows" };

        for (var i = 0; i < systemdir.Length; i++)
        {
            systemdir[i] = source + "\\" + systemdir[i];
        }

        //Now Create all of the directories
        foreach (string dirPath in Directory.GetDirectories(source, "*", SearchOption.AllDirectories).Where(d => systemdir.All(e => !d.StartsWith(e))))
        {
            Console.WriteLine(dirPath);
            if (System.IO.Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath.Replace(source, target));
            }

        }

        //Copy all the files & Replaces any files with the same name
        foreach (string newPath in Directory.GetFiles(source, "*.*", SearchOption.AllDirectories))
        {
            if (System.IO.Directory.Exists(Path.GetDirectoryName(newPath.Replace(source, target))))
            {

                if (System.IO.File.Exists(newPath))
                {
                    File.Copy(newPath, newPath.Replace(source, target), true);
                    // Use a try block to catch IOExceptions, to
                    // handle the case of the file already being
                    // opened by another process.
                    try
                    {
                        System.IO.File.Delete(newPath);
                    }
                    catch (System.IO.IOException e)
                    {
                        Console.WriteLine(e.Message);
                        return;
                    }
                }
            }
        }
    }
}

}

(Simply Ged) 建议的编辑:

using System;
using System.IO;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string serialNum = "MS001";
            string userName = Environment.UserName;
            string sourcecpath = "C:\\Users\\" + userName + "\\Desktop\\Dummy\\Local C";
            string targetcpath = "C:\\Users\\" + userName + "\\Desktop\\Dummy\\Desktop\\" + serialNum + "\\Local C";
            copy(sourcecpath, targetcpath);
        }

    public static void copy(string source, string target)
    {

        string[] systemdir = new string[] {  "Error", "Intel", "PerfLogs", "Program Files", "Users", "Windows" };

        for (var i = 0; i < systemdir.Length; i++)
        {
            systemdir[i] = source + "\\" + systemdir[i] + "\\";
        }

        //Now Create all of the directories
        var directoryList = Directory.GetDirectories(source, "*", SearchOption.AllDirectories).Where(d => !systemdir.Any(e => d.StartsWith(e)));

        foreach (string dirPath in directoryList)
        {
            Console.WriteLine(dirPath);
            if (System.IO.Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath.Replace(source, target));
            }

        }

        //Copy all the files & Replaces any files with the same name
        foreach (var directory in directoryList)
        {
            foreach (string newPath in Directory.GetFiles(source, "*.*", SearchOption.AllDirectories))
            {
                if (System.IO.Directory.Exists(Path.GetDirectoryName(newPath.Replace(source, target))))
                {

                    if (System.IO.File.Exists(newPath))
                    {
                        File.Copy(newPath, newPath.Replace(source, target), true);
                        // Use a try block to catch IOExceptions, to
                        // handle the case of the file already being
                        // opened by another process.
                        try
                        {
                            System.IO.File.Delete(newPath);
                        }
                        catch (System.IO.IOException e)
                        {
                            Console.WriteLine(e.Message);
                            return;
                        }
                    }
                }
            }
        }
    }
}

}

标签: c#

解决方案


您可以将 a 附加\\systemdir变量的末尾:

systemdir[i] = source + "\\" + systemdir[i] + "\\";

这只会匹配确切名称的文件夹

例如C:\Windows\Intel\

除此之外,您可以改进循环并且仅循环遍历systemdir数组中的项目

for (var i = 0; i < systemdir.Length; i++)
{
    systemdir[i] = source + "\\" + systemdir[i];
}

如果您从该数组中添加或删除项目,则循环将自动处理它

编辑

YouWhere子句不排除这些项目。您需要将其更改为:

.Where(d => !systemdir.Any(e => d.StartsWith(e)))

翻译为:

wheresystemdir没有任何匹配的开头d

编辑

正如您在第二条评论中提到的,您的第二条foreach是使用source文件夹来找出要复制的文件和目录,这不排除systemdir文件夹。您需要将要处理的目录列表存储在变量中:

var directoryList = Directory.GetDirectories(source, "*", SearchOption.AllDirectories).Where(d => !systemdir.Any(e => d.StartsWith(e)));

该列表现在仅包含您要复制的目录,即它已从您的systemdir数组中排除了这些目录。

您现在可以更改您的第一个foreach以使用该变量:

foreach (string dirPath in directoryList)
{
    ...
}

现在我们循环遍历您需要复制的目录的相同列表过程:

foreach (var directory in directoryList)
{
    //Copy all the files & Replaces any files with the same name
    foreach (string newPath in Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories))
    {
        ...
    }


推荐阅读