2010-09-04 10 views
7

Ho bisogno di una procedura che controlli se nuove cartelle/file sono stati aggiunti a una determinata cartella selezionata. Ho bisogno di questa procedura per eseguire all'avvio dell'applicazione in modo che il tempo di elaborazione in questa fase sia importante.Come posso verificare se il contenuto di una cartella è stato modificato

Immagino di poter creare un registro dello stato corrente, registrare lo stato precedente, ordinare e confrontarli.

  1. Per prima cosa ho bisogno di sapere se c'è un altro modo.

  2. Secondo se non c'è altro modo, qual è il modo migliore per trovare la differenza tra due elenchi di percorsi di file: struttura e algoritmi.

Old State:

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

Nuovo stato:

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

sto cercando c:\firstfolder\secondFolder\c.doc.

+0

Avete bisogno di sapere * se * c'è stato un cambiamento, vale a dire un 'risultato boolean', o ciò che il cambiamento è stato, vale a dire un' List '? =) – Rob

+0

necessita della lista ... Sono riuscito a farlo nel modo seguente creando un file xml per lo stato precedente e quello corretto e confrontandolo usando "Eccetto" come suggerito da Timwi: http://stackoverflow.com/questions/3647958/find-the-delta-between-two-xelements-using-except-c ...funziona ma è lento – Asaf

risposta

1

Dal momento che l'applicazione non è in esecuzione in modo continuo, l'utilizzo di FileSystemWatcher non sembra una buona opzione per te, ma volevo menzionarlo poiché potrebbe suscitare alcune idee dalla tua parte.

Se si dispone di un elenco del vecchio Stato e creare un elenco del nuovo stato è possibile utilizzare un algoritmo simile a quello delineato here per confrontare le due liste per determinare le aggiunte e le eliminazioni dal momento che il primo elenco è stato creato. Quella risposta accettata al collegamento fornito ha anche una bella soluzione che funziona molto bene se gli elenchi non sono ordinati.

+0

Gli hashset sembrano promettenti ma non ne so nulla ... Proveremo a provare a saperne di più su di loro. Grazie – Asaf

3

È possibile utilizzare la classe FileSystemWatcher, penso che stia facendo esattamente quello che si sta cercando.

+3

Questo funziona solo quando l'applicazione è in esecuzione. Non rileverà i cambiamenti che si verificano tra le invocazioni del programma. – ChrisF

+1

+1 @CyberDude: grazie, è bello sapere che questo listener esiste, (mi ha fatto chiedere se ne ho bisogno anche io), ma come ChrisF ha detto che cattura solo i cambiamenti durante il runtime, e ho bisogno di sapere quali sono i cambiamenti dal precedente esecuzione dell'applicazione – Asaf

0

Penso che la migliore scommessa sia la ricorsione attraverso la directory e il salvataggio dello stato. Qualcosa del genere:

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

Dopo questo, avrete la lista dello stato. Se hai anche il vecchio stato nell'elenco. Confronta gli elenchi ora.

+0

Nessuna necessità di tutte le ricorsioni, Directory.GetDirectories e in Framework 4.0 Directory.EnumerateDirectories può attraversare l'intero albero in una singola chiamata. Per non parlare del fatto che il codice di cui sopra richiederebbe anche ulteriori dichiarazioni P/Invoke, che non sono mostrate. –

0

È possibile salvare le informazioni sull'ora dell'ultimo stato. Quindi puoi semplicemente confrontare i tempi di creazione di file e cartelle con quello. Il seguente codice può darti un'idea:

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

Modifica: Questa non è una risposta completa. Non puoi ottenere i file cancellati da questo codice.

2

Penso che il quadro di sincronizzazione possa essere quello che stai cercando.

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

+0

Ho bisogno di confrontare due cartelle che hanno le stesse sottocartelle ma i file sono uguali solo per nome ... vengono creati separatamente in modo che il loro contenuto, dimensioni e altri parametri non siano uguali alla cartella di origine. Questa è la ragione per cui non credo che questa soluzione funzionerà per me questa volta. Grazie Asaf – Asaf

Problemi correlati