2009-12-06 2 views
0

Я просто изучаю C# (занимаюсь этим около двух дней), и я решил, что для оплодотворения я перестрою старое приложение, которое я сделал в VB6 для синхронизации файлов (обычно по сети).Как сравнить одну коллекцию файлов с другой в C#?

Когда я написал код в VB 6, он работал примерно так:

  1. Создать Scripting.FileSystemObject
  2. Создание объектов каталога для источника и назначения
  3. Создать список файлов объектов для источника и пункт назначения
  4. Перейдите по исходному объекту и проверьте, существует ли он в пункте назначения
    • , если нет, то создайте его
    • если да, то проверьте, чтобы увидеть, если версия источника/новее больше, и если да, то перезаписать другой

До сих пор, это то, что у меня есть:

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» собственность, но я специально искал способ поиска существующий сбор/список файлов, а не живые проверки файловой системы для каждого файла, так как я буду делать поэтому по сети и постоянно возвращаясь к многотысячному файловому каталогу, медленная медленная медленная работа.

Спасибо заранее.

ответ

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(); 
    } 
}  

Непроверенные хотя: р

+4

Также для вспомогательных каталогов используется Path.Combine (sourcePath, subDir.Name) вместо sourcePath + subDir.Name –

+0

Также посмотрите на метод GetFileSystemInfos: http://msdn.microsoft.com/en-us/ library/system.io.directoryinfo.getfilesysteminfos.aspx – Svish

+0

Что касается вашей заметки: я понимаю, но это риск, который я принимаю, перегружая работу с получением списка файлов, поэтому мне не нужно делать индивидуальные проверки на множество -thousand файлов. Большое спасибо за ваш ответ, я прошу проверить синтаксис «Любые»! – Dereleased

4

Одна маленькая деталь, вместо

sourcePath + subDir.Name 

I будет использовать

System.IO.Path.Combine(sourcePath, subDir.Name) 

Путь выполняет надежные, независимые от ОС операции с файловыми и папными именами.

Также я замечаю, что optRecursive.Checked выскочил из ниоткуда. По сути хорошего дизайна, сделать что параметр:

bool syncFiles(string sourcePath, string destPath, bool checkRecursive) 

И так как вы говорите, может быть использованы для большого количества файлов, следить за .NET 4, он имеет IEnumerable замены GetFiles (), который позволит вам обрабатывать это потоковым способом.

+0

+1, спасибо за этот совет! – Dereleased

+0

+1 для обозначения «И поскольку вы упоминаете, что он может использоваться для большого количества файлов, следите за .NET 4, у него есть замена IEnumerable для GetFiles(), которая позволит вам обрабатывать это потоковым способом». – sehe

+0

+1 Используя 'Path.Combine', вы получите информацию о тех проблемах, где заканчивается косая черта, а иногда и нет. Это делает жизнь болью. – ErocM

 Смежные вопросы

  • Нет связанных вопросов^_^