【问题标题】:Find the difference of two folders and delete files查找两个文件夹的差异并删除文件
【发布时间】:2012-12-19 08:41:39
【问题描述】:

我有两个文件夹:FolderA 和 FolderB 我想删除 FolderA 中也存在于 FolderB 中的文件。 (即常用文件将从文件夹A中删除)

如何在 C# 中最有效地做到这一点? (这是项目中的一个关键点,它必须尽可能高效)

感谢

【问题讨论】:

  • 如果文件名相同或者其他参数(如大小、属性等)是否也被比较,是否认为文件相同?
  • 什么都不需要比较,如果文件名相等,文件就相等

标签: c# performance file-io


【解决方案1】:

这简单、易读且高效:

var common = from f1 in Directory.EnumerateFiles(folderA, "*.*", SearchOption.AllDirectories)
             join f2 in Directory.EnumerateFiles(folderB, "*.*", SearchOption.AllDirectories)
             on Path.GetFileName(f1) equals Path.GetFileName(f2)
             select f1;

foreach (string file in common)
{
    File.Delete(file);
}

假设您只想比较文件名(和扩展名)。

【讨论】:

  • 我不太熟悉这种语法,但它看起来很紧凑。我们如何有效地扩展它以便删除两个文件(在 f1 和 f2 上)?
  • @EngelbertCoder:那么你需要使用匿名类型。这是代码差异:select new { File1 = f1, File2 = f2 }; foreach (var files in common) { File.Delete(files.File1); File.Delete(files.File2); }。顺便说一句,这就是 Linq 查询语法。您也可以使用method syntax,但我更喜欢使用Joins 进行查询。
  • @EngelbertCoder: Here 是关于Join 的一些信息以及它的性能。
【解决方案2】:

您可以在 LINQ 的帮助下完成此操作。见here

【讨论】:

    【解决方案3】:

    如果您只想比较文件名,可以这样做,我对此代码进行了快速测试,它可以工作:

            string pathA = @"C:\New FolderA";
            string pathB = @"C:\New FolderB";
    
            var filesA = Directory.GetFiles(pathA).Select(path => Path.GetFileName(path));
            var filesB = Directory.GetFiles(pathB).Select(path => Path.GetFileName(path));
    
            var toBeDeleted = filesA.Intersect(filesB);
            foreach (string filename in toBeDeleted)
                File.Delete(Path.Combine(pathA, filename));
    

    【讨论】:

    • 这个答案有三个缺点。 1.如果他想搜索子目录(SearchOption.AllDirectories),因为你正在与根目录组合,所以不起作用。 2. 与EnumerateFiles 方法不同,需要首先将所有内容加载到内存中 3. 如果 OP 还想包含文件大小或其他属性,则扩展性较差。
    • OP 说他只需要比较文件名。如果他使用的是低于 4 的 .NET 版本,则不能使用EnumerateFiles
    【解决方案4】:
     string[] FolderAFiles = Directory.GetFiles(@"Path");
                string[] FolderBFiles = Directory.GetFiles(@"BPath");
                foreach (string Files in FolderAFiles)
                {
                    if (FolderBFiles.Contains(Files))
                    {
                        File.Delete(Files);
                    }
                }
    

    试试这个

    【讨论】:

      【解决方案5】:

      这是另一种解决方案。

      var filesInB = System.IO.Directory.GetFiles("FolderB");
      Array.ForEach(System.IO.Directory.GetFiles("FolderA"), delegate(string fileName){
          if (filesInB.Contains(fileName)) System.IO.File.Delete(fileName);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-26
        • 2014-02-02
        • 2020-06-13
        • 1970-01-01
        • 1970-01-01
        • 2014-11-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多