C# C根据名称比较文件列表,但不返回完整路径

C# C根据名称比较文件列表,但不返回完整路径,c#,list,file,compare,C#,List,File,Compare,我正在写一个方法,我希望能够根据文件名比较两个不同目录中的文件列表,然后将第二个目录中不存在的所有文件存储到一个列表中,以供以后使用,最有可能创建另一个方法来复制/移动这些文件 在我查看文件列表文件保留列表并尝试获取文件的完整路径之前,一切似乎都正常工作。它最终指向我的bin/debug路径 我相信这是因为在我的查询中,我专门查询要比较的file.Name,而不是file.FullName。这是因为全名将返回路径和文件名,我无法将其用于比较语句var filesleening=FileList1

我正在写一个方法,我希望能够根据文件名比较两个不同目录中的文件列表,然后将第二个目录中不存在的所有文件存储到一个列表中,以供以后使用,最有可能创建另一个方法来复制/移动这些文件

在我查看文件列表文件保留列表并尝试获取文件的完整路径之前,一切似乎都正常工作。它最终指向我的bin/debug路径

我相信这是因为在我的查询中,我专门查询要比较的file.Name,而不是file.FullName。这是因为全名将返回路径和文件名,我无法将其用于比较语句var filesleening=FileList1.ExceptFileList2.ToList

因此,我的问题是,如何仅根据名称比较两组文件,然后将异常列表的完整路径存储到第三个列表中,以便稍后用于复制/移动

以下是我的方法:

   public static List<string> CompareFiles(string ComparePath1, string ComparePath2)
    {
        List<string> FileList1 = new List<string>();
        List<string> FileList2 = new List<string>();
        List<string> CompareFileList = new List<string>();
        DirectoryInfo directory1 = new DirectoryInfo(ComparePath1);
        FileInfo[] files1 = directory1.GetFiles("*.*", SearchOption.TopDirectoryOnly);
        DirectoryInfo directory2 = new DirectoryInfo(ComparePath2);
        FileInfo[] files2 = directory2.GetFiles("*.*", SearchOption.TopDirectoryOnly);

        //Queries the given directory for filenames
        var query1 = from file in files1
                where (!file.Attributes.HasFlag(FileAttributes.Hidden))
                    select (file.Name);
        foreach (var file in query1)
        {
            FileList1.Add(file);
        }

        var query2 = from file in files2
                    where (!file.Attributes.HasFlag(FileAttributes.Hidden))
                    select (file.Name);
        foreach (var file in query2)
        {
            FileList2.Add(file);
        }

        var FilesRemaining = FileList1.Except(FileList2).ToList();

        foreach (var file in FilesRemaining)
        {
            string fullFile = Path.GetFullPath(file);
            CompareFileList.Add(fullFile);
            Console.WriteLine(fullFile);
        }

        return CompareFileList;

    }

使用此选项,您可以保留FileInfo对象,并且仍然只使用它们的名称计算Except列表

//More efficient way to get your files.
IEnumerable<FileInfo> files1 = directory1
    .GetFiles("*.*", SearchOption.TopDirectoryOnly)
    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden));
IEnumerable<FileInfo> files2 = directory2
    .GetFiles("*.*", SearchOption.TopDirectoryOnly)
    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden));

//It uses the FileNameComparer class to compare to values.
IEnumerable<FileInfo> filesRemaining = files1.Except(files2, new FileNameComparer());
下面是FileNameComparer类

public class FileNameComparer : IEqualityComparer<FileInfo>
{
    public bool Equals(FileInfo x, FileInfo y)
    {
        //Here is where the magic is happening.
        return x.Name == y.Name;
    }

    //You need this too, altougt, I am not quite sure when it gets used.
    public int GetHashCode(FileInfo obj)
    {

        return obj.Name.GetHashCode();
    }
}

似乎您最好先创建FileList1和2列表,然后对Exception调用使用本地相等运算符:当然,最后对循环进行一个小的调整。实际上,您可以只调用一个Where调用,而不是Exception…@Steve您在说什么?这个编译得很好。如果您使用LINQ语法,那么您需要这样做,但是正如您所看到的,我不知道,是时候开始了bed@Steve我也去过那里,我的朋友D@TomD如果它起作用,你可以将它设置为其他人的正确答案,他们正在寻找解决同一问题的方法。好奇为什么有人否决了这一点?这看起来是一个合理的答案。不确定,没有尝试这个解决方案,但另一个对我有效。
class Program
{
    static void Main(string[] args)
    {
        foreach ( var f in CompareFiles(@"x:\tmp\dir_1", @"x:\tmp\dir_2") )
        {
            Console.WriteLine(f);
        }

        Console.ReadKey();
    }

    public static List<string> CompareFiles(string comparePath1, string comparePath2)
    {
        //Queries the given directory for filenames
        var fileList1 = (from file in new DirectoryInfo(comparePath1).GetFiles("*.*", SearchOption.TopDirectoryOnly)
                         where !file.Attributes.HasFlag(FileAttributes.Hidden)
                         select file.Name).ToList();

        var fileList2 = (from file in new DirectoryInfo(comparePath2).GetFiles("*.*", SearchOption.TopDirectoryOnly)
                         where !file.Attributes.HasFlag(FileAttributes.Hidden)
                         select file.Name).ToList();
        return fileList1.Except(fileList2)
                        .Select(file => Path.Combine(comparePath1, file))
                        .ToList();
    }
}