我正在编写一种我希望能够根据文件名比较两个不同目录的文件列表的方法,然后存储所有不存在的文件第二个目录到以后使用的列表中(最有可能创建另一种复制/移动这些文件的方法)。
一切似乎都在正常工作,直到我查看文件列表(文件交易列表)并尝试获取文件的完整路径。它最终指向我的垃圾箱/调试路径。
我相信这是因为在我的查询中,我专门查询file.name以比较,而不是file.fullname。原因是因为全名将返回路径和文件名,我无法将其用于我的比较语句(var filesRemaining = filelist1.except(filelist2).tolist().tolist();)。
。所以我的问题变成了,我如何基于名称比较2组文件,然后将异常列表的完整路径存储到第三列表中,我可以稍后将其用于复制/移动?
这是我的方法:
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对象,并且仍然只使用其名称来计算列表。
//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());
这是fileenamecomparer类。
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();
}
}
class Program
{
static void Main(string[] args)
{
foreach ( var f in CompareFiles(@"x:tmpdir_1", @"x:tmpdir_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();
}
}