Checksumme beschleunigen

celph_titled

Erfahrenes Mitglied
Hallo zusammen,

vielleicht hat jemand eine Idee hierzu:

Ich hab mir ein Programm gebastelt, dass mir quasi ein Backup eines Verzeichnisses erstellt, aber nicht komprimiert sondern eine genaue Kopie. Da sich im Quellverzeichnis immer nur wenig verändert will ich nicht bei jedem Durchlauf alles neu rüberkopieren sondern nur das was sich verändert hat, also praktisch ein inkrementelles Backup. Wenn eine Datei sowohl im Quell- als auch im Zielverzeichnis vorhanden ist muss ich die ja vergleichen. Dazu hab ich die CRC-Checksumme aus java.util.zip eingebaut, aber bei 9 GB in ungefähr 2000 Dateien dauert das schon ne Weile. Ich weiß nicht ob das die optimale Lösung ist
Code:
private long getChecksum(File f) {
	try {
		CRC32 c = new CRC32();
		byte b[] = new byte[1024];
		FileInputStream in = new FileInputStream(f);
		int len = 0;
		while((len=in.read(b))>=0) {
			c.update(b,0,len);
		}
		in.close();
		return c.getValue();
	}
	catch(Exception e) {
		return -1;
	}
}
Die Funktion wird jeweils für die Quell- und die Zieldatei aufgerufen. Die Dateien sind so zwischen 600kB und 5MB groß.
Gibt es ne Möglichkeit das zu beschleunigen? Die Puffergröße zu ändern bringt leider kaum was. Die Adler-Checksumme soll ja schneller sein, aber auch unzuverlässig. Ist das so oder kann ich die schon benutzen?
Oder weiß jemand sonst eine Möglichkeit die Dateien schneller zu vergleichen?

Danke im Voraus
 

procurve

Erfahrenes Mitglied
Die Checksummen der gesicherten Dateien würde ich nicht jedes Mal nue berechnen lassen, sondern in einer Datenbank sichern, somit sparst du dir schon mal einiges. (Datenbankabfrage ist wesentlich schneller erledigt, als die Berechnung einer Prüfsumme).

Eventuell kannst du dir den Checksummen-Algorithmus anschauen und gucken, ob sich dieser beschleunigen lässt. Außerdem wäre es möglich, dass du nicht über die gesamte Datei eine checksumme berechnest, sondern nur über deren Attribute wie Größe und letztes Änderungsdatum.
 

takidoso

Erfahrenes Mitglied
Man kann auch statt einer DB schlicht ein gewöhnliches Text-File oder wenn man mag auch ein Properties-File zum Speichern der Checksummen verwenden, das ist Geschmacksache.
Ich würde vielleicht auch vor einer Checksummen-Berechnung die Länge der Datei anschauen und vergleichen und nur bei gleichstand auf eine Checksumme zurückgreifen.
 

Kai008

Erfahrenes Mitglied
Wenn man eine Datei verändert, wird die doch dann nicht mitgesichert?!
Da er ja nur die Checksum der alten Datei in der DB hat, und das Backup die selbe hat.

Von der Adler habe ich noch nie was gehört, aber unter "unzuverlässig" würde ich Kollisionen und nicht Fehler im Vergleich verstehen.
 
Zuletzt bearbeitet:

takidoso

Erfahrenes Mitglied
Wenn ich mir den Anwendungsfall nochmal so anschaue, bin ich mir nicht so sicher ob eine Checksumme hier eigetnlich notwendig ist. Klassisch verwendet man doch eigetnlich dann Checksummen, wenn man feststellen möchte, dass eine Datei nicht korupt ist, die man vielleicht gerade übertragen/runtergeladen hat.
In diesem Fall geth es einzig um die Frage ist die Datei identisch mit der alten. Das kann man neben vorabchecken der Dateilänge dann auch IMHO bequem über byteweisen vergleich tun, bis man einen Unterschied bemerkt. Auf diese weise müsste man weder die eine noch die andere Datei von vorn bis ganz nach hinten lesen, sondern hätte, Im Falle eines Unterschiedes viel schneller diesen bemerkt.

Also ich würde auf Checksummen hier vermutlich sogar ganz verzichten, wenn es lediglich um inkrementelles Backup geht.
 

procurve

Erfahrenes Mitglied
Byteweise Dateivergleiche sind doch wesentlich teurer (ständiges Umpositionieren der Leseköpfe), als das Berechnen einer Checksumme und der Vergleich mit einer archivierten Checksumme.

Eventuell wäre ein 2-stufiges System praktikabel, das zuerst anhand einfacher Kriterien (Dateilänge, Änderungsdatum, Permission-Flags) die Gleichheit überprüft und die Checksumme erst dann zu Hilfe nimmt, wenn die Dateien im ersten Schritt als gleich eingestuft wurden.
 

Anime-Otaku

Erfahrenes Mitglied
Als kleine Idee:
Ich würde mir überlegen vielleicht einfach den lastmodified Zeitstempel der Datei als Vergleich zu nehmen.
Klar vielleicht wurde die Datei nur angefasst, aber nichts daran geändert, aber vielleicht ist das in deinem Fall der einfachste Weg.
 

takidoso

Erfahrenes Mitglied
Byteweise Dateivergleiche sind doch wesentlich teurer (ständiges Umpositionieren der Leseköpfe), als das Berechnen einer Checksumme und der Vergleich mit einer archivierten Checksumme.
Naja ich meinte mit dem Byteweisen Vergleich nicht, dass da ungepuffert die DAteien gelesen werden sollen ;-)
Ich denke mal es hängt auch schwer von der Datei ab u.U. sogar vom Dateityp. Wurde vorrangig vorne geändert, würde der Vergleich sehr schnell sein. Würde vorrangig hinten geändert dauert es erheblich länger. Hat man einen Dateityp, der vielleicht in sich soetwas ähnliches wie eine Checksumme schon beherbergt, das dann glücklicherweise ganz oben steht, hat man super gewonnen.
Für den ganz allgemeinen Fall, kann ich mir vorstellen, dass bei einem direkten Vergleich (spekulativ) statistisch die Hälfte von beiden Dateien gelesen werden müsste. Das entspräche dann von den gelesenen Daten dann spekulativ statistisch gesehen wenn man eine Datei von vorne nach hinten liest, also ungefär dem selben Aufwand wie mit der Checksumme, die man zwischenspeichert für die eine eventuell neue Dateiversion. Abgesehen von dem Schreiblesekopfwechsel, der bei entsprechenden Puffer nicht ganz so häufig auftreten sollte und ebenfalls abgesehen von der Zeit die benötigt wird eine Checksumme zu errechnen, käme dass vielleicht ganz gut aufs selbe raus.
Aber wie schon mehrfach gesagt ist es sinnvoll länge der Dateien vorher zu prüfen.
vom Datum und von Berechtigungen würde ich, wenn es "nur" um Inhalt geht absehen.
 
Zuletzt bearbeitet: