我正在学习C#(现在已经习惯了2天了)我已经决定,为了学习目的,我将重建一个我在VB6中制作的用于同步文件的旧应用程序(通常是通过网络)
当我在VB 6中编写代码时,它的工作方式大致如下:
Scripting.FileSystemObject
到目前为止,这就是我所拥有的:
private bool syncFiles(string sourcePath, string destPath) {
DirectoryInfo source = new DirectoryInfo(sourcePath);
DirectoryInfo dest = new DirectoryInfo(destPath);
if (!source.Exists) {
LogLine("Source Folder Not Found!");
return false;
}
if (!dest.Exists) {
LogLine("Destination Folder Not Found!");
return false;
}
FileInfo[] sourceFiles = source.GetFiles();
FileInfo[] destFiles = dest.GetFiles();
foreach (FileInfo file in sourceFiles) {
// check exists on file
}
if (optRecursive.Checked) {
foreach (DirectoryInfo subDir in source.GetDirectories()) {
// create-if-not-exists destination subdirectory
syncFiles(sourcePath + subDir.Name, destPath + subDir.Name);
}
}
return true;
}
我已经阅读过似乎主张使用FileInfo或DirectoryInfo对象来检查“Exists”属性的示例,但我特意寻找一种方法来搜索现有的文件集合/列表,而不是实时检查每个文件的文件系统,因为我将通过网络这样做并不断回到一个数千个文件目录是缓慢的慢。
先谢谢。
答案 0 :(得分:5)
GetFiles()
方法只会获取确实存在的文件。它不构成不存在的随机文件。所以你要做的就是检查它是否存在于另一个列表中。
这可能有用:
var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();
foreach (var file in sourceFiles)
{
if(!destFiles.Any(x => x.Name == file.Name))
{
// Do whatever
}
}
注意: 在完成对GetFiles()
的调用后,您当然无法保证某些内容未发生变化。例如,如果您稍后尝试复制文件,则可能已删除或重命名该文件。
也许可以通过使用Except
方法或类似方法以某种方式更好地完成。例如:
var sourceFiles = source.GetFiles();
var destFiles = dest.GetFiles();
var sourceFilesMissingInDestination = sourceFiles.Except(destFiles, new FileNameComparer());
foreach (var file in sourceFilesMissingInDestination)
{
// Do whatever
}
FileNameComparer的实现方式如下:
public class FileNameComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
return Equals(x.Name, y.Name);
}
public int GetHashCode(FileInfo obj)
{
return obj.Name.GetHashCode();
}
}
虽然未经测试:p
答案 1 :(得分:4)
一个小细节,而不是
sourcePath + subDir.Name
我会用
System.IO.Path.Combine(sourcePath, subDir.Name)
Path在文件和文件名上执行可靠的,独立于操作系统的操作。
此外,我注意到optRecursive.Checked
突然冒出来。作为一个好的设计问题,请将其作为参数:
bool syncFiles(string sourcePath, string destPath, bool checkRecursive)
既然你提到它可能用于大量文件,请留意.NET 4,它有一个IEnumerable替代GetFiles(),它可以让你以流媒体方式处理它。