DuplicateFinder | Version: 1.0

    • Release

    Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von kevios11.

      BjöNi schrieb:

      Zuerst einen Datenblock am Ende der Dateien vergleichen
      Ist auch finde ich die sinnvollste methode. anfang macht keinen sinn da header oft gleich und fürn hash muss die ganze datei eingelesen werden^^

      Dodo schrieb:

      aber das is FW 4.0

      Man kann's auch mit normalen Threads fummeln ... ist halt nur umständlicher. Die Frage ist ja, ob du gezielt nur jeweils eine Datei einliest und bearbeitest (sequentiell) oder ob du mehrere Dateien gleichzeitg bearbeitest, bzw zumindest das Einlesen und das Vergleichen trennst. Die Idee ist ja: Während die Datei gelesen wird, hat die CPU eigentlich nix zu tun (DMA). Also wenn die erste Datei eingelesen wurde und an die Vergleichsfunktion übergeben wurde, könnte man eigentlich immer schon die nächste einlesen.

      R=Read (Datei), C=Vergleichen, .=Leerlauf

      Quellcode

      1. R.R.R.R.R.
      2. .C.C.C.C.C

      vs:

      Quellcode

      1. RRRRR.
      2. .CCCCC
      Einmal gabs nen Fehler/Exception "Funktion nur für Dateien kleiner 2 GB" (oder so ähnlich).
      Außerdem ist mir aufgefallen:
      Hab einen Ordner mit 2 (identischen) Dateien prüfen lassen. Beide 1 GB. Ergebnis "Duplikat" nach wenigen Sekunden ... ??? Sollte er nicht beide Dateien komplett prüfen, wenn er nicht sicher ist? Dafür gings imho zu schnell. Oder machst du auch nen Byteweisen Vergleich? Durch den Windows-Cache werden Filesystem Benchmarks ja manchmal stark verfälscht.

      Was mir noch aufgefallen ist:
      Hab ihn mal auf meinen Bilder Ordner losgelassen (da passierte auch der Fehler). CPU Auslastung 6-12%. Also nur 1 Kern (von 4+4). Hab selber mal ein bißchen gespielt und mit Multithreading etc komm ich immerhin auf knapp 20% Auslastung (alle Dateien gleicher Länge, in diesem fall 300 von 6.000 werden pauschal gehasht).
      Du hast mit der aktuellen Version von mir getestet und da kam die Exception?? O.o

      Die 1GB Datei war ein Duplikat oder war das eine Fehlmeldung? In der momentanen Version hashed er jede Datei und vergleicht dann. Wobei ich habs noch nicht mit so großen Dateien getestet.
      version 143

      Quellcode

      1. {"Die Datei ist zu lang. Dieser Vorgang unterstützt derzeit nur Dateien mit einer Größe von weniger als 2 GB."}
      2. bei System.IO.File.ReadAllBytes(String path)
      3. bei DuplicateFinder.Hash.SHA1File(String Filename)
      4. bei DuplicateFinder.frmMain.makeFileHash()
      5. bei System.Threading.ExecutionContext.runTryCode(Object userData)
      6. bei System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
      7. bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      8. bei System.Threading.ThreadHelper.ThreadStart()


      Warum machst du readallbytes?

      using fs as new filestream(path, 1<<20)
      b()=sha.computehash(fs)
      Ich schreib mal, wie ich mir das ganze vorstelle:

      Stufe 1 (single thread): Dateien einlesen
      Dateien werden bestimmt (manuell, nicht mit Directory.GetFiles) und gleichzeitig in ein Dictionary eingetragen mit Länge, List(Of Fileinfo). Immer wenn diese Stufe eine Datei findet, die eine schon mal gefundene Länge hat (List.Count>1) werden die entsprechenden Dateien an Stufe 2 weitergereicht.

      Stufe 2 (multithreaded): Dateiinhalt Kurzcheck
      Aus allen erhaltenen Dateien werden an bestimmten Stellen Bytes gelesen und daraus ein möglichst einmlaiger Wert gebildet. Eingetragen wird wieder in ein Dic mit "Hash", List(Of Fileinfo). Wie in Stufe 1: Wenn eine Datei mit existierendem "Hash" (crc, bitfupsel,...) gefunden wird, wird an Stufe 3 weitergegeben.

      Stufe 3 (multithreaded): Dateiinhalt komplett hashen
      Jetzt werden alle Dateien komplett gehasht und bei Treffern wird an die Ausgabestufe weitergeleitet.

      Stufe 1, 2 und 3 können jeweils parallel laufen, so das möglichst wenig Leerlauf durch warten auf IO auftritt. Hat dann auch den Vorteil, dass man Stufe 2 und 3 mit mehr oder weniger Threads laufen lassen kann um so zb einen Hintergrund-Scan zu machen. Aber auf jeden Fall hätte man den Vorteil, dass durch die vielen "gleichzeitigen" Festplattenzugriffe evtl das NCQ besser zuschlagen kann.

      Das ganze könnte man dann auch prima mit DataflowBlocks realisieren ;)
      (ok, das wäre dann wieder FW 4/4.5 ;) )
      Ne ne ich nutze GetFiles() für die Files in einem Ordner und GetDirectories() für die Verzeichnisse und gehe diese dann Rekursiv durch, das mit allen Unterverzeichnissen klappt ja nicht wegen Leseberechtigungen, zwar stürzt meine Funktion auch noch ab, aber nur weil ich den Permission Check dadrin vergessen habe =)
      Habs heute mal gebraucht und muss sagen bei rund ~3k dateien ging das recht flott - innerhalb 10 sekunden hatte ich das ergebniss, sehr gute Arbeit :)
      Moderatorin: "Apropo ritzen.." Shin Chan: "hoho sie hat Po ritze gesagt"
      "saying to buy a mac because your anti-virus expired is like saying you're out of condoms so you're just going to go fuck dudes"
      "Wie auch in anderen Threads kann ich leider nichts bieten außer vielleicht spaß beim Skypen aber mehr leider auch nicht." - Sind kinder pornos nicht verboten?