2010-09-04 19 views
7

muszę procedurę, która sprawdza, czy nowe foldery/pliki zostały dodane do danego wybranego folderu. Potrzebuję tej procedury do uruchomienia po uruchomieniu aplikacji, dlatego czas przetwarzania na tym etapie jest ważny.Jak mogę sprawdzić, czy zawartość folderu została zmieniona

Chyba mogę zrobić dziennik stanu obecnego, log z poprzedniego stanu, sortowania i porównać je.

  1. Najpierw muszę wiedzieć, czy jest inny sposób.

  2. Po drugie, jeśli nie ma innego sposobu, jaki jest najlepszy sposób, aby znaleźć różnicę pomiędzy dwoma listami plików ścieżek: zarówno struktury i algorytmy.

Old State:

c:\firstfolder\a.doc 
c:\firstfolder\b.doc 
c:\firstfolder\secondFolder\a.doc 
c:\firstfolder\secondFolder\b.doc 

Nowy stan:

c:\firstfolder\a.doc 
c:\firstfolder\b.doc 
c:\firstfolder\secondFolder\a.doc 
c:\firstfolder\secondFolder\b.doc 
c:\firstfolder\secondFolder\c.doc 

szukam c:\firstfolder\secondFolder\c.doc.

+0

Czy trzeba znać * * jeśli nastąpiła zmiana, to znaczy 'wynik boolean' lub co była zmiana, to znaczy' List '? =) – Rob

+0

Potrzebuję listy ... Udało mi się to zrobić w następujący sposób, tworząc plik xml dla poprzedniego i prawidłowego stanu i porównując go używając "Except", jak sugerował Timwi: http://stackoverflow.com/questions/3647958/find-the-delta-between-two-xelements-using-except-c ...działa, ale jest wolny – Asaf

Odpowiedz

1

Ponieważ aplikacja nie działa nieprzerwanie, użycie opcji FileSystemWatcher nie wydaje się być dobrym rozwiązaniem dla Ciebie, ale chciałem o tym wspomnieć, ponieważ może to wywołać u Ciebie pewne pomysły.

Jeśli masz listę dawnego stanu i utworzyć listę nowego stanu można użyć algorytmu jak ten przedstawionym here porównać dwie listy, aby ustalić, uzupełnień i skreśleń ponieważ pierwsza lista została utworzona. Ta akceptowana odpowiedź na podany link ma również dobre rozwiązanie, które działa bardzo dobrze, jeśli listy nie są sortowane.

+0

HashSets wygląda obiecująco, ale nic o nich nie wiem ... Postaram się dowiedzieć o nich więcej. Dzięki – Asaf

3

Można użyć klasy FileSystemWatcher, myślę, że robi dokładnie to, czego po.

+3

Działa to tylko wtedy, gdy aplikacja jest uruchomiona. Nie wykryje zmian, które wystąpią między wywołaniami programu. – ChrisF

+1

+1 @CyberDude: dziękuję, dobrze wiedzieć, że ten słuchacz istnieje, (zastanawiałem się, czy też go potrzebuję), ale jak Chris powiedział, że przechwytuje tylko zmiany w czasie wykonywania, i muszę wiedzieć, co się zmieniło od czasu poprzedni bieg aplikacji – Asaf

0

Myślę, że najlepszym rozwiązaniem jest recursing pośrednictwem katalogu i zapisywanie stanu. Coś takiego:

public List<FileData> RecurseDirectory(string directory, int level, out int files, out int folders) 
     { 
      IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); 
      //long size = 0; 
      files = 0; 
      folders = 0; 
      WIN32_FIND_DATA findData; 
      List<FileData> list = new List<FileData>(); 

      IntPtr findHandle; 

      // add global escape chars if not present. 
      if (directory.StartsWith(@"\\?\")) 
      { 
       findHandle = FindFirstFile(directory + @"\*", out findData); 
      } 
      else 
      { 
       findHandle = FindFirstFile(@"\\?\" + directory + @"\*", out findData); 
      } 


      if (findHandle != INVALID_HANDLE_VALUE) 
      { 
       //if file exists: 


       do 
       { 
        if ((findData.dwFileAttributes & FileAttributes.Directory) != 0) 
        { 
         //if it's a directory: 

         if (findData.cFileName != "." && findData.cFileName != "..") 
         { 
          //increment folder counter. 
          folders++; 

          int subfiles, subfolders; 
          string subdirectory = directory + (directory.EndsWith(@"\") ? "" : @"\") + 
           findData.cFileName; 
          //Console.WriteLine("Dir:" + subdirectory); 

          //add it to list 
          String path = subdirectory; 
          FileData tempFileData = new FileData(); 
          tempFileData.path = path; 
          tempFileData.fileProperties = findData; 
          list.Add(tempFileData); 

          //allows -1 to do complete search. 
          if (level != 0) 
          { 
           //recurse through to next subfolder 
           list.AddRange(RecurseDirectory(subdirectory, level - 1, out subfiles, out subfolders)); 

           folders += subfolders; 
           files += subfiles; 
          } 
         } 
        } 
        else 
        { 
         // File 
         files++; 
         string subfile = directory + (directory.EndsWith(@"\") ? "" : @"\") + 
           findData.cFileName; 
         //Console.WriteLine("File:" + subfile); 
         //list.Add("File:" + subfile); 
         String path = subfile; 
         FileData t = new FileData(); 
         t.path = path; 
         t.fileProperties = findData; 
         list.Add(t); 

         //size += (long)findData.nFileSizeLow + (long)findData.nFileSizeHigh * 4294967296L; 
        } 
       } 
       while (FindNextFile(findHandle, out findData)); 
       FindClose(findHandle); 

      } 

      return list; 
     } 

Po tym będziesz miał listę stanu. Jeśli masz stary stan na liście również. Porównaj listy Teraz.

+0

Nie ma potrzeby wykonywania wszystkich rekursji, Directory.GetDirectories oraz w Directory 4.0 Directory.EnumerateDirectories można przechodzić przez całe drzewo w jednym wywołaniu. Nie wspominając, że powyższy kod wymagałby również dodatkowych deklaracji P/Invoke, które nie są pokazywane. –

0

można zapisać informacje o czasie ostatniego państwa. Wtedy możesz po prostu porównać czasy tworzenia plików i folderów z tym. Poniższy kod może dać ci pomysł:

foreach(FileInfo f in dir.GetFiles() { 
    if(f.CreationTime > dtLastState) { 
     //do some interesting stuff 
    } 
} 

Edytuj: To nie jest kompletna odpowiedź. Nie można uzyskać usuniętych plików za pomocą tego kodu.

2

Myślę, że Framework Sync może być tym, czego szukasz.

http://msdn.microsoft.com/en-us/sync/default.aspx

+0

Potrzebuję porównać dwa foldery, które mają te same foldery podrzędne, ale pliki są takie same tylko po nazwie ... są one tworzone osobno, więc ich zawartość, rozmiar i inne parametry nie są równe folderowi źródłowemu. Dlatego nie sądzę, aby twoje rozwiązanie zadziałało na mnie tym razem. Dzięki Asaf – Asaf

Powiązane problemy