C# 使用LINQ C比较列表中的文件

C# 使用LINQ C比较列表中的文件,c#,linq,list,file,compare,C#,Linq,List,File,Compare,我有两个文件集合作为列表。我目前使用2 x foreach循环遍历每个集合,并匹配下面显示的文件。在LINQ和.RemoveAt中有没有更快的方法可以实现这一点 我需要文件名和文件长度匹配 var sdinfo = new DirectoryInfo(srcPath); var ddinfo = new DirectoryInfo(dstPath); var sFiles = new List<FileInfo>(sdinfo.Get

我有两个文件集合作为列表。我目前使用2 x foreach循环遍历每个集合,并匹配下面显示的文件。在LINQ和.RemoveAt中有没有更快的方法可以实现这一点

我需要文件名和文件长度匹配

        var sdinfo = new DirectoryInfo(srcPath);
        var ddinfo = new DirectoryInfo(dstPath);

        var sFiles = new List<FileInfo>(sdinfo.GetFiles("*", SearchOption.AllDirectories));
        var dFiles = new List<FileInfo>(ddinfo.GetFiles("*", SearchOption.AllDirectories));

        foreach (var sFile in sFiles)
        {
            bool foundFile = false;
            int i = 0;

            foreach (var dFile in dFiles)
            {
                if (sFile.Name == dFile.Name && sFile.Length == dFile.Length)
                {
                    foundFile = true;
                    dFiles.RemoveAt(i);
                }
                i += 1;
            }
        }
干杯。

您可以使用以下方法:


在上面的示例中,您从数据文件中获取所有不在数据文件中的文件。

首先,如果执行此代码,将引发异常,因为您在迭代数据文件时修改了枚举数据文件。但是,为了复制枚举,可以使用。这也会有一个问题,因为无论删除多少,都会增加索引,这也会导致一个错误——俗语off中有一个例外

如果你担心速度,不要担心。Linq使用使用foreach和yield返回的方法,并且从源代码中可以看到这些方法

如果您想使代码更易于阅读,那么这就是Linq变得有用的地方。其中之一是:

假设您随后正在迭代dList,您还可以使用:

最后,如果您需要保留sFiles,下面的代码将其打包在一起

List<string> sFiles, dFiles;
dFiles = ddinfo.GetFiles("*", SearchOption.AllDirectories)
    .Except(sFiles = sdinfo.GetFiles("*", SearchOption.AllDirectories));

如果您想以空间换取时间,可以构建一个包含一个列表的哈希集,并在哈希集中查找另一个列表的每个元素。查找是O1,而循环是开着的

我假设您的示例代码中有输入错误。sdinfo和ddinfo都使用srcPath。参见第1行和第2行是的,这是O型。好位置,干杯。编辑。OP要求更快的解决方案,即两个循环。LINQ对EXPECT有不同的算法吗?我意识到这是更少的代码行。我对性能很好奇。@KC-NH Except方法使用哈希集的Set类内部实现:。这看起来很有用。基本上,如果有一个不匹配或丢失,我会在方法上返回false。
foreach(var fileToRemove in sFiles.Join(dFiles, s => s, d => d, (s, d) => s).ToArray())
    dFiles.Remove(fileToRemove);
var files = sdinfo.GetFiles("*", SearchOption.AllDirectories)
    .Except(ddinfo.GetFiles("*", SearchOption.AllDirectories));
List<string> sFiles, dFiles;
dFiles = ddinfo.GetFiles("*", SearchOption.AllDirectories)
    .Except(sFiles = sdinfo.GetFiles("*", SearchOption.AllDirectories));