2010-08-28 6 views
3

J'ai 2 volumes de disque dur (l'un est une image de sauvegarde de l'autre), je veux comparer les volumes et lister tous les fichiers modifiés, afin que l'utilisateur puisse sélectionner ceux qu'il veut restaurer.Comment comparer 2 volumes et lister les fichiers modifiés?

Actuellement, je suis récursif à travers le nouveau volume et je compare les horodatages de chaque fichier aux fichiers de l'ancien volume (s'ils se trouvent dans l'ancien volume). De toute évidence, c'est une approche maladroite. C'est long et mauvais!

Existe-t-il un moyen efficace de le faire? - J'utilise FindFirstFile et j'aime recopier le volume, et rassembler des informations sur chaque fichier (pas très lent, juste quelques minutes).
- J'utilise Volume Shadow Copy pour sauvegarder.
- Le volume de sauvegarde est distant, donc je ne peux pas surveiller en permanence le volume réel.

+1

Pour obtenir des réponses plus utiles, vous devez ajouter sous quelle plate-forme votre outil doit fonctionner. POSIX, win32 ou autre chose? Les différentes plateformes ont des sémantiques de système de fichiers différentes. – maxschlepzig

+0

Désolé, ajouté le tag win32 maintenant. Merci – lalli

+0

Combien de temps? * Comment es-tu récursif à travers le volume et en comparant les choses? Pas à la main, j'espère. Êtes-vous familier avec les langages de script? Perl? Checksums? – Beta

Répondre

2

Une partie de ceci dépend de la façon dont les deux volumes sont dupliqués; s'il s'agit de copies «vraies» du point de vue du système de fichiers (p.copies d'ombre ou d'autres copies au niveau du bloc), vous pouvez faire quelques petites choses délicates en ce qui concerne USN, qui est la technologie générale que d'autres vous suggèrent d'examiner. Vous pourriez vouloir regarder une API comme FSCTL_READ_FILE_USN_DATA, par exemple. Cette API vous permettra de comparer deux copies différentes d'un fichier (encore une fois, en supposant qu'ils sont le même fichier avec le même numéro de référence de fichier à partir de sauvegardes de niveau bloc). Si vous vouliez être largement apatride, ceci et les API similaires vous aideraient beaucoup ici. Mon algorithme ressemblerait à quelque chose comme ceci:

foreach(file in backup_volume) { 
    file_still_exists = try_open_by_id(modified_volume) 
    if (file_still_exists) { 
     usn_result = compare_usn_values_of_files(file, file_in_modified_volume) 
     if (usn_result == equal_to) { 
      // file hasn't changed at all 
     } else { 
      // file has changed (somehow) 
     } 
    } else { 
     // file was deleted (possibly deleted and recreated) 
    } 
} 
// we still don't know about files new in modified_volume 

Tout cela dit, mon expérience me porte à croire que ce sera plus compliqué que mon explication hors des boutons de manchette conseils à. Cela pourrait être un bon point de départ, cependant.

Si les volumes ne sont pas des copies au niveau bloc l'un de l'autre, il sera très difficile de comparer les numéros USN et les ID de fichier, voire impossible. Au lieu de cela, vous pouvez très bien aller par nom de fichier, ce qui sera difficile sinon impossible sans ouvrir tous les fichiers (les temps peuvent être modifiés par les applications, les tailles et les temps peuvent être périmés dans les requêtes findfirst/next, et vous avoir à gérer les cas supprimés puis recréés, renommer les cas, etc.). Donc, sachant combien de contrôle que vous avez sur l'environnement est très important.

+0

J'avance vaguement sur cette approche. Merci mon pote! – lalli

0

En supposant que vous ne comparez pas chaque fichier du nouveau volume à chaque fichier de l'instantané, c'est la seule façon de le faire. Comment allez-vous trouver quels fichiers ne sont pas modifiés sans les regarder tous?

+0

C'est l'approche que je suis passé à (je prends le diff de chaque fichier dans le nouveau volume avec l'ancien snapshot), mais c'est très lent. Je pensais peut-être à un niveau inférieur (analyser et comparer les blocs ou quelque chose?) – lalli

+1

@lalli: Il n'y a pas d'API de niveau inférieur (supporté) que 'FindFirstFile' et ses amis. Même si vous alliez le faire en analysant vous-même le format NTFS au format disque, je doute que vous puissiez le faire plus rapidement que ntfs.sys de Windows. –

0

Je ne suis pas un programmeur Windows. Cependant, vous ne devriez pas avoir la fonction stat pour récupérer l'heure modifiée d'un fichier. Triez les fichiers en fonction de l'heure de modification. Les fichiers dont l'heure de modification est supérieure à la durée de votre dernière sauvegarde sont ceux qui vous intéressent.

Pour la première fois, vous pouvez parcourir le volume de sauvegarde pour déterminer le temps de mod max et le temps créé par votre ensemble intéressé. Je suppose que les répertoires d'intérêt ne sont pas modifiés dans le volume de sauvegarde.

+0

'stat' n'est pas une fonction Windows. –

+0

ne devrait pas GetFileTime faire le travail. Aussi, vous n'avez même pas besoin de trier si vous connaissez le temps de mod max. Vous pouvez obtenir la liste en un seul passage du volume actuel. – aeh

+0

@ user433874: Non, 'GetFileTime' requiert un handle de fichier, ce qui signifie que vous devez ouvrir chaque fichier en question. 'FindFirstFile' et les amis ** retournent déjà l'heure ** lorsque vous énumérez un répertoire, donc je ne vois pas vraiment ce que vous voulez dire ici. –

1

Au lieu d'attendre jusqu'à ce que des changements ont eu lieu, puis l'analyse du disque entier pour trouver les (généralement peu) les fichiers qui ont changé, je mis en place un programme visant à utiliser ReadDirectoryChangesW pour surveiller les changements comme ils se produisent. Cela vous permettra de construire une liste de fichiers avec un minimum d'agitation et de déranger.

+0

Notez que cela ne va pas fonctionner à travers les redémarrages ou autres amusants. En outre, cela peut conduire à des résultats amusants lorsque Volume Shadow Copy est en jeu. Si une telle solution est acceptable, vous devriez envisager d'utiliser le journal Usn (http://msdn.microsoft.com/en-us/library/aa363798.aspx) à la place. –

+0

@Billy: oui, je pensais que si vous deviez le faire de façon routinière, vous l'implémenteriez probablement comme un service à démarrer automatiquement.J'hésite à recommander le journal USN, simplement parce que je ne l'ai jamais utilisé, mais d'après ce que je me rappelle de la documentation, c'est probablement un bon choix. –

+0

@Jerry: Le problème est que même si vous vous enregistrez pour démarrer automatiquement, vous ne pouvez pas démarrer assez tôt pour intercepter les changements apportés par, disons, le noyau. Toute solution basée sur la surveillance ne sera * pas * fiable à 100% lors des redémarrages * dans toutes les circonstances. –

0

Sans savoir plus de détails sur ce que vous essayez de faire ici, c'est difficile à dire. Cependant, quelques conseils sur ce que je pense vous essayez d'atteindre:

  • Si vous êtes seulement préoccupé par les volumes NTFS, je suggère à la recherche dans le journal USN/changement de l'API. Ils existent depuis 2000. De cette façon, après l'inventaire initial, vous ne pouvez voir que les changements à partir de ce point. Un bon point de départ pour cela, même si un très vieil article est ici: http://www.microsoft.com/msj/0999/journal/journal.aspx
  • De plus, en utilisant les API USN, vous pouvez omettre l'étape de hachage et enregistrer simplement les informations du journal vous-même (cela deviendra plus clair quand/si vous regardez dans lesdites API)
  • La première fois en comparant le contenu d'un lecteur, utilisez un hachage tel que SHA-1 ou MD5.
  • Stockez les hachages et autres informations de ce type dans une base de données quelconque. Par exemple, SQLite3. Notez que cela peut prendre une énorme quantité d'espace lui-même. Un coup d'oeil rapide sur mon dossier audio avec des fichiers de 40k + entraînerait ~ 750 megs d'informations MD5.
+0

Un hachage MD5 de chaque fichier sur le volume sera probablement assez volumineux - prévoyez d'avoir plusieurs Go d'espace juste pour votre index. –

Questions connexes