2010-02-22 28 views
7

Ich habe ein Programm, das Dateien in zwei Ordnern vergleicht. Ich möchte feststellen, ob eine Datei umbenannt wurde, die neueste (zuletzt umbenannte) Datei bestimmen und den Namen der alten Datei entsprechend aktualisieren.Wie kann ich feststellen, wann eine Datei zuletzt umbenannt wurde?

Um dies zu erreichen, würde ich überprüfen, ob die neueste Datei Bit für Bit identisch mit der alten ist, und wenn dies der Fall ist, benennen Sie einfach die alte Datei um, damit sie der neuen Datei entspricht.

Das Problem ist, ich habe nichts zu Schlüssel, um mir zu sagen, welche Datei zuletzt umbenannt wurde.

Ich würde gerne eine Eigenschaft wie FileInfo.LastModified, aber für Dateien, die umbenannt wurden.

Ich habe bereits Lösungen wie FileSystemWatcher angeschaut, und das ist nicht wirklich das, wonach ich suche. Ich möchte meinen Synchronizer wann immer ich will laufen lassen, ohne mich um einen bestimmten Prozess kümmern zu müssen, der den Zustand eines Ordners verfolgt.

Irgendwelche Ideen?

Antwort

1

A: Mindestens auf NTFS, können Sie alternate data streams to a file befestigen. Bei Ihrer ersten Synchronisierung können Sie einfach eine GUID in einem ADS an die Quelldateien anhängen, um sie zu markieren.

B: Wenn Sie keinen Schreibzugriff auf die Quelle haben, speichern Sie Hashwerte der Dateien, die Sie in Ihrem Zielrepository synchronisiert haben. Wenn sich die Quelle ändert, müssen Sie nur die Quelldateien hashen und nur Bit für Bit vergleichen, wenn die Hashes kollidieren. Je nach Qualität und Geschwindigkeit Ihrer Hash-Funktion sparen Sie dadurch viel Zeit.

+0

... und kombinieren Sie es natürlich mit 'LastModified'. –

+0

Ich habe bereits Hashes von Verzeichnissen an jedem Ende gespeichert. Matching-Daten Bit für Bit ist bereits möglich. Ich habe nur gehofft, dass ich mir vielleicht etwas Bandbreite sparen kann, wenn ich über langsame Netzwerke synchronisiere, indem ich bereits vorhandene Dateien verschiebe. Es sieht so aus, als gäbe es keine nicht NTFS-spezifische Möglichkeit, dies zu tun. –

+0

Dies funktioniert möglicherweise auch über zugeordnete Treiber (oder Netzwerkfreigaben), vorausgesetzt, das Quellvolume ist NTFS. Wenn Sie es noch nicht gefunden haben, kann dies eine Hilfe sein: http://www.codeproject.com/KB/cs/ntfstreces.aspx –

0

Sie könnten möglicherweise eine Konfigurationsdatei erstellen, die eine Liste aller erwarteten Namen in dem Ordner enthält, und dann, wenn eine Datei in dem Ordner kein Mitglied der erwarteten Liste von Namen ist, bestimmen, dass die Datei dann gewesen ist umbenannt. Dies würde jedoch eine weitere Arbeitsschicht hinzufügen, da Sie die Liste jedes Mal ändern müssen, wenn Sie dem Ordner eine neue Datei hinzufügen möchten.

+0

Das funktioniert nicht wirklich mit meinem Werkzeug. Es soll zwei beliebige Verzeichnisse in beide Richtungen synchronisieren. –

+0

Haben Sie versucht, unvergleichlich zu sein? Es ist ein großartiges Werkzeug für das, wonach Sie suchen. – Aaron

0

Dateisysteme verfolgen dies im Allgemeinen nicht.

Da Sie scheinen unter Windows zu sein, können Sie GetFileInformationByHandle() verwenden. (Entschuldigung, ich kenne das C# -Äquivalent nicht.) Sie können die "Datei-Index" -Felder in der zurückgegebenen Struktur verwenden, um zu sehen, ob Dateien den gleichen Index wie etwas haben, das Sie zuvor gesehen haben. Beachten Sie, dass Hardlinks auch denselben Index haben.

Alternativ könnten Sie Dateiinhalte irgendwie hash.

Ich weiß nicht genau, was Sie zu tun versuchen, also kann ich Ihnen nicht sagen, ob einer dieser Punkte Sinn macht. Es könnte sein, dass die vernünftigste Antwort lautet: "Nein, das kannst du nicht tun."

+0

Ich bin mir ziemlich sicher, dass das nicht das ist, was das OP sucht, aber es ist trotzdem eine interessante Idee ... wahrscheinlich besser als der Plan des OP, zu testen, ob die beiden Dateien Bit-identisch sind, um eine Umbenennung durchzuführen. – rmeador

+0

Das ist eine großartige Idee, aber es gibt viele Probleme mit der Datei-ID. Der Abschnitt "Bemerkungen" sagt: "Der Bezeichner, der in den Elementen nFileIndexHigh und nFileIndexLow gespeichert ist, wird als Datei-ID bezeichnet. [So hoher Index und niedriger Index => ** Datei-ID **] Unterstützung für ** Datei-ID ** s ist Datei system-specific [also, nicht alle Dateisysteme können es unterstützen ... NTFS wahrscheinlich, wer weiß, ob der Rest das tut?] Datei-IDs sind nicht garantiert, im Laufe der Zeit einzigartig zu sein, weil Dateisysteme sie wiederverwenden können [aber für ein Schnappschuss der Zeit, die sie sein werden, denke ich.] In einigen Fällen kann sich die Datei-ID für eine Datei im Laufe der Zeit ändern. " – Alexandru

1

Wenn Sie auf einem NTFS-Laufwerk laufen, können Sie die change journal aktivieren, die Sie dann für Dinge wie Ereignisse umbenennen können. Allerdings müssen Sie ein Administrator sein, um es zu starten, und es wird Speicherplatz belegen. Leider kenne ich keine spezifischen C# -Implementierungen zum Lesen des Journals.

0

Ich würde eine CRC (zB CRC example) von (alle?) Die Dateien in den 2 Verzeichnissen die letzte Aktualisierungszeit mit dem CRC-Wert, Dateiname usw. speichern. Danach durch die Listen Finding Maches durch die CRC und dann die Datumswerte verwenden, um zu entscheiden, was zu tun ist.

+0

Ich mache das schon. Das Problem besteht darin, dass beim Umbenennen einer Datei keine Zeitstempel geändert werden. –

+0

Oh - soweit mir bekannt ist, können Sie eine Datei nicht umbenennen und ihre Zeitmarke nicht ändern. Wenn Sie könnten, wäre es ein ziemlich niedriger API-Aufruf (nicht wahrscheinlich von C# ausgesetzt) –

Verwandte Themen