Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Алгори Синхронизатор для двух папок и файлов в них


Автор: ddll 14.3.2011, 18:16
Здравствуйте!
Пишу синхронизатор для двух папок и файлов в них.
Вероятно надо рекурсивная функция сравнения.
Мне надо проверять по дате модификации файлов и в этом нет проблемы.
Проблема состоит в том что папка- в папке - в папке 5 папок и много файло- в каждой папке еще есть файлы и папки степень вложености может быть очень большой.
Как двигаться и с чего начать никак не могу придумать!

Проблема в том что не могу придумать до конца рекурсивную функцию. 

Заранее спасибо за помощь!

Автор: mihryak 15.3.2011, 12:37
алгоритм таков:
- синхронизировать файлы в двух папках
- создать отстутствующие папки и там, и там
- повторить эти действия для папок, уже существующих и там, и там

Код

        class DirectoryComparer : IEqualityComparer<DirectoryInfo>
        {
            #region IEqualityComparer<DirectoryInfo> Members

            public bool Equals(DirectoryInfo x, DirectoryInfo y)
            {
                return StringComparer.OrdinalIgnoreCase.Equals(x.Name, y.Name);
            }

            public int GetHashCode(DirectoryInfo obj)
            {
                return obj.Name.ToLower().GetHashCode();
            }

            #endregion
        }

        static void SyncFolders(DirectoryInfo left, DirectoryInfo right)
        {
            SyncFiles(left, right);

            var comparer = new DirectoryComparer();

            var leftChildDirectories = left.GetDirectories();
            var rightChildDirectories = right.GetDirectories();

            leftChildDirectories.Except(rightChildDirectories, comparer).ToList()
                .ForEach(d => CopyFolder(d, right.CreateSubdirectory(d.Name)));
            rightChildDirectories.Except(leftChildDirectories, comparer).ToList()
                .ForEach(d => CopyFolder(d, left.CreateSubdirectory(d.Name)));

            leftChildDirectories.Intersect(rightChildDirectories, comparer).ToList()
                .ForEach(d => SyncFolders(d, new DirectoryInfo(Path.Combine(right.FullName, d.Name))));
        }

        static void CopyFolder(DirectoryInfo source, DirectoryInfo target)
        {
            source.GetFiles().ToList()
                .ForEach(f => f.CopyTo(Path.Combine(target.FullName, f.Name)));
            source.GetDirectories().ToList()
                .ForEach(d => CopyFolder(d, target.CreateSubdirectory(d.Name)));            
        }

        static void SyncFiles(DirectoryInfo left, DirectoryInfo right)
        {
            ........
        }

Автор: ddll 15.3.2011, 18:59
Спасибо большое но  я уже попробывал написать похожую рекурсивную функцию
Код

const string SKYDRIVE_FOLDER = @"dir1";
const string SERVER_FOLDER = @"dir2";
static void Main(string[] args)
{
CompareDir(SERVER_FOLDER,SKYDRIVE_FOLDER);
}

static void CompareDir(string FromDir, string ToDir)
{
Directory.CreateDirectory(ToDir);
foreach (string s1 in Directory.GetFiles(FromDir))
{

string s2 = ToDir + "\\" + Path.GetFileName(s1);
if (File.GetLastWriteTime(s1) > File.GetLastWriteTime(s2).AddHours(-13))
{
File.Copy(s1, s2,true);
File.SetLastWriteTime(s2, File.GetLastWriteTime(s1));
}
}
foreach (string s in Directory.GetDirectories(FromDir))
{
CompareDir(s, ToDir + "\\" + Path.GetFileName(s));
}
}
}




Автор: jonie 15.3.2011, 23:37
а можно взять готовое Microsoft Sync Framework, там  и провайдер синхронизации папок уже есть

Автор: ddll 16.3.2011, 11:45
Да нет проблемма в другом что у меня даты на сервере и на локальном компьютере разные.
Как вариант пришол к выводу хранить дату последней синхронизации и отслеживать файлы измененные после неё.

Автор: mrbrooks 16.3.2011, 16:32
Цитата(ddll @  16.3.2011,  11:45 Найти цитируемый пост)
Да нет проблемма в другом что у меня даты на сервере и на локальном компьютере разные.

Это что реализация машины времени?

Я к тому - отчего бы не синхронизироваться с сервером по NTP/SNTP? А то выглядит, как то не кошерно.

Автор: AntonL 20.3.2011, 14:48
MD5 файлов считать, и можно хранить где нибудь, если не надо в обе стороны синхронизировать.

Автор: ddll 20.3.2011, 15:04
Спасибо  AntonL надо в две стороны просто время будет не совсем одинаковым у меня между выполнением программы и времям даты модификации на сервере.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)