Checksumme für ein File berechnen

reibi

Top Contributor
Hi

Hab ein kleines abgespektes Programm, welches eigentlich nur das prinzip zeigen soll, welches ich da nutze; so siehts aus :


//IMPORTS
Java:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

import java.util.Properties;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;

//METHODE
Java:
    public static long getChecksum(File thefile) throws Exception {
        FileInputStream myFIS = new FileInputStream(thefile);
        CheckedInputStream myCIS = new CheckedInputStream(myFIS, new CRC32());

        BufferedInputStream myBIS = new BufferedInputStream(myCIS);

        //Schleife
        while (myBIS.read() != -1) {
        } // end while

        //Checksumme holen
        return myCIS.getChecksum().getValue();
    } // end getChecksum()

Es liefert die Checksumme der Datei.

Also ich hab WinXP laufen auf n Core2Duo mit 3,16 Ghz

Das berechnen der Checksumme für:
100MB-Files dauert 1 Sekunde --> Kein Problem
3GB-Files dauer 40 Sekunden ---> Das ist ein Problem

Hab rausgefunden das :
Java:
        //Checksumme holen
        return myCIS.getChecksum().getValue();
das hier praktisch "NICHTS" an Zeit braucht ... max ein paar MilliSecs

und das hier:
Java:
        //Schleife
        while (myBIS.read() != -1) {
        } // end while
die 40 Sekunden.


nun die FRAGE:
Kann ich das irgebndwie zeitlich abkürzen=
ZB mit nem RandomAccessFile oder ApacheCommonsIO oder was Andres ... oder das ich den STream vorher nicht durchrödeln muss oder es gibt n ganz anderen Ansatz.

Danke Jungs und Mädels für Eure potentielle GehirnSchmalzEnergieVerbrauchsAktion ;-)
 
S

SlaterB

Gast
was ist schon eine Checksumme, wenn sie nicht jedes Byte wenigstens einmal liest?
schneller wirds nicht gehen, oder kann z.B. dein Betriebssystem die 3GB mal eben schneller an eine andere Stelle kopieren (nicht verschieben)?

Why FileInputStream is slow. | Preston L. Bannister { random memes }
and 51MB/s reading from disk (which we can assume is as fast as data can be read from this machine’s SATA disk).

du hast vielleicht 100 MB/s oder noch höher, egal, irgendwo ist eine Grenze,
und wenn man nur eine Datei groß genug wählt ist es irgendwann langsam

-----

auch Parallelverarbeitung dürfe das nicht erhöhen,
es ginge höchstens wenn die Datei bereits auf mehreren Festplatten/ vielleicht unterschiedlichen Rechnern vorliegt,
dann könnten diese parallel je 50 MB pro Sekunde schaffen, unterschiedliche Teile der Datei lesen, nach x Sec ihre y Teilergebnissie zusammentragen und die dann nur noch passend verrechnen ;)
 
Zuletzt bearbeitet von einem Moderator:

Geeeee

Bekanntes Mitglied
Java:
        //Schleife
        while (myBIS.read() != -1) {
        } // end while
nicht byteweise lesen, sondern mit ein bisschen Puffer.
Java:
int buffersize = 1024;//*1024
byte[] buffer = new byte[buffersize];
while(myBIS.read(buffer) ....

Edit: Sehe gerade den Vorposter: Wäre es mit dem Buffer nicht wirklich "etwas" schneller. War nun ungetest mal ausm Kopf geholt :)
 
S

SlaterB

Gast
kann sein dass es durch den Buffer schneller wird, aber wohl nur minimal,
es ist ja schon ein BufferedInputStream in der Kette, der liest auf jeden Fall dicke Buffer,
ob die bytes dann in ein neues byte-Array kopiert werden oder mit tausenden Einzelaufrufen..,

ok, wird schon bisschen was bringen, für Verringerung von Methodenaufrufen bin ich eigentlich auch immer ;)
 

reibi

Top Contributor
Hi Geee unds Slater

also das mit dem Buffer bringts wirklich !! DANKE ;-)

Checksumme erstellen für ein 3 GB file, dauert nun noch 12Sek anstatt 40Sek. Also das ist auf jeden schon eine 3mal bessere Performance.

Um das mit dem Puffer richtig zu verstehen, noch Fragen:

1.) Es ist völlig egal ob der Buffer 1024, 2048 oder 4096 gross ist, schneller gehts durch vergrößern des Puffers auch nicht, warum eigentlich?
2.) Kann der Puffer eine falsche Größe haben, (zB 1117 oder 1023) gibt es irgendwelche Probleme?
3.) Warum ist denn der defaultPuffer nicht gleich 1024? Ist er kleiner? - Warscheinlich ja - warum eigentlich?

Danke und Gruss ;-)
 
G

Gast2

Gast
Um das mit dem Puffer richtig zu verstehen, noch Fragen:

1.) Es ist völlig egal ob der Buffer 1024, 2048 oder 4096 gross ist, schneller gehts durch vergrößern des Puffers auch nicht, warum eigentlich?
2.) Kann der Puffer eine falsche Größe haben, (zB 1117 oder 1023) gibt es irgendwelche Probleme?
3.) Warum ist denn der defaultPuffer nicht gleich 1024? Ist er kleiner? - Warscheinlich ja - warum eigentlich?

Danke und Gruss ;-)

1) Kommt auf deine Hardware, Betriebsysteme und Treiber an. Eine Festplatte hat nunmal eine maximale Leserate, einen festgelegten Cache und der Rest der IO Operationen in System sind da auch interessant. In 12s 3GB lesen ist schon recht sportlich - macht immer hin 256MB/s.

2) Jein, direkt schlimm ist das nicht. Aber wenn von einer Platte Blöcke gelesen werden sind das auch immer 2er Potenzen an bytes.

3) [c]The default buffer size of 8192[/c]
BufferedReader
 

reibi

Top Contributor
Hi
The default buffer size of 8192

Ja das steht auch so in der Javadoc.

Nur, wenn ich "8192" als Puffergroße explizit angebe,
dann geht das auch 3 mal schneller als wenn ich das nicht täte.

Auf die Lesezeit hat es auch KEINEN Einfluss
wenn ich als Puffergröße irgendwas zwischen 128 und 8192 eingebe. Das geht immer 3mal schneller als ohne Angabe des Puffers(Default).


Kommt auf deine Hardware, Betriebsysteme und Treiber an.

Wo könnte es denn da Probleme geben, wenn ich die Puffergröße auf 1024 stelle?
Bei älteren Geräten bzw.Festplatten oder eher bei weiterentwickelten, die erst in 5 Jahren rauskommen?
Kann es sein, das meine Software auf irgendwelchen Rechnern dann nicht läuft, egal ob alt oder neu?

Gruss
reibsen
 
S

SlaterB

Gast
da habe ich mich ja gehörig verschätzt mit der Optimierungsmöglichkeit, ich bin aber nach wie vor der Meinung, dass durch den BufferedInputStream immer genau 8192 gelesen werden,
in 8192-Blöcken gehen sie auch am CheckedInputStream vorbei,

der Rest ist nur die Frage, wie diese Daten von BufferedInputStream an den Aufrufer weitergeleitet werden,
ob vom byte[] in BufferedInputStream alles ein einen oder wenigen Aufrufen in ein neues Array kopiert oder per 8000 Einzelanfragen immer nur ein byte zurückgegeben wird,

inwiefern die Buffer-Anfrage schneller ist kann man auch mit folgender Untersuchung etwas besser testen:
Java:
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        File f = new File("test.txt");

        System.out.println("start");
        System.out.println(", " + getChecksum(f));
        for (int i = 17; i >= 0; i--)
        {
            int size = (int)Math.pow(2, i);
            System.out.println(", " + getChecksumBuf(f, size));
        }
    }

    public static long getChecksum(File thefile)
        throws Exception
    {
        FileInputStream myFIS = new FileInputStream(thefile);
        CheckedInputStream myCIS = new CheckedInputStream(myFIS, new CRC32());
        InputStream myBIS = new BufferedInputStream(myCIS);

        long time = System.currentTimeMillis();
        while (myBIS.read() != -1)
        {
        }
        long t = (System.currentTimeMillis() - time);
        System.out.print("time: " + t);
        return myCIS.getChecksum().getValue();
    }

    public static long getChecksumBuf(File thefile, final int size)
        throws Exception
    {
        FileInputStream myFIS = new FileInputStream(thefile);
        CheckedInputStream myCIS = new CheckedInputStream(myFIS, new CRC32());
        InputStream myBIS = new BufferedInputStream(myCIS);
        // InputStream myBIS = myCIS;

        long time = System.currentTimeMillis();
        final byte[] buf = new byte[size];
        while (myBIS.read(buf, 0, size) != -1)
        {
        }
        long t = (System.currentTimeMillis() - time);
        System.out.print("time: " + t + ", size: " + size);
        return myCIS.getChecksum().getValue();
    }
}
Ausgabe bei mir bei einer 100 MB-Datei:
Code:
time: 3690, 2353550512
time: 313, size: 131072, 2353550512
time: 297, size: 65536, 2353550512
time: 313, size: 32768, 2353550512
time: 297, size: 16384, 2353550512
time: 312, size: 8192, 2353550512
time: 329, size: 4096, 2353550512
time: 328, size: 2048, 2353550512
time: 328, size: 1024, 2353550512
time: 329, size: 512, 2353550512
time: 344, size: 256, 2353550512
time: 375, size: 128, 2353550512
time: 453, size: 64, 2353550512
time: 548, size: 32, 2353550512
time: 781, size: 16, 2353550512
time: 1173, size: 8, 2353550512
time: 2001, size: 4, 2353550512
time: 3721, size: 2, 2353550512
time: 7146, size: 1, 2353550512
300 ms ist der Basissatz, soviel dauert das Einlesen in 8192er-Blöcken, evtl. gehts schneller wenn man den Buffer von BufferedInputStream erhöht,
die restlichen Sekunden darüber hängen meiner Meinung nach direkt mit der Anzahl der Aufrufe zusammen,

bei size 1 ist der Buffer-Aufruf langsamer als ein read(), weil unnötig in einen Buffer kopiert wird, mehr Parameter sind zu übergeben usw.,
bei size 2 halbiert sich die Anzahl nötiger Aufrufe, es werden ca. 3.4 Sekunden gespart,
wenn man von den insgesamt ~7.1 Sekunden 0.3 als Grundzeit abzieht, dann ist das genau die Hälfte der variablen Zeit

im weiteren funktioniert das ungefähr genauso

wenn man erstmal bei 512 oder 1024 ist, dann hat man sowieso schon 99.8% und mehr der nötigen Aufrufe eingespart,
eine weitere Verdopplung bringt deshalb gar nichts mehr, außer im Promille-Bereich

edit:
der ganze BufferedInputStream ist eigentlich unnötiger Overhead, da werden endlos bytes kopiert ohne Nutzen,
lies mit 8192-Buffer direkt aus dem CheckedInputStream oder vielleicht mit noch höheren Buffern
(edit: selbst getestet, bringt aber nix)
 
Zuletzt bearbeitet von einem Moderator:

LoR

Bekanntes Mitglied
Java:
    private static long getChecksumFast(File file) throws IOException {
        CRC32 crc = new CRC32();
        FileChannel channel = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            channel = fis.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(8192); //16384
            buffer.clear();

            while (channel.read(buffer) != -1) {
                buffer.flip();
                crc.update(buffer.array(), 0, buffer.limit());
            }
        } finally {
            if (channel != null) {
                channel.close();
            }
        }
        return crc.getValue();
    }

//EDIT: Bzw. nimm die von SlaterB vorgeschlagene Methode.
 
Zuletzt bearbeitet:

Geeeee

Bekanntes Mitglied
da habe ich mich ja gehörig verschätzt mit der Optimierungsmöglichkeit, ich bin aber nach wie vor der Meinung, dass durch den BufferedInputStream immer genau 8192 gelesen werden,
...

Das Problem liegt meines Erachtens einfach am Call von read(). Da wird nur ein char / int eingelesen und ich glaube auch nicht, dass er in dem Moment anfängt, 8192 bytes zu lesen und nur einen Teil davon ausgibt, damit er sie dann später ausm Cache holen kann :)
 
S

SlaterB

Gast
was kannst du sonst sagen außer dass du etwas lesen willst?
wie viel ist egal, wenn du nur soviel haben willst wie du anfragst, dann direkt auf dem Stream darüber,
wenn du beliebige Datenanfragen in verdeckten 8192er-Anfragen organisieren willst, dann Buffered
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
AssELAss Best Practice Checksumme über jede Spalte zweier Tabellen und vergleichen Allgemeine Java-Themen 3
ARadauer Checksumme über BigDecimal Werte Allgemeine Java-Themen 11
foobar Checksumme in C++ Allgemeine Java-Themen 9
B Algorithmus für Arbeit mit fehlenden Listenelementen? Allgemeine Java-Themen 1
kodela Eingabe für TextArray bedingt sperren Allgemeine Java-Themen 3
Karl_Der_Nette_Anfänger Hat wer ne Lösung für verknüpfte Postleitzahlen? (Baum/Wurzel Struktur) Allgemeine Java-Themen 11
R 11 GB File lesen ohne zu extrahieren Filedaten Bereich für Bereich adressieren dann mit Multi-Thread id die DB importieren Allgemeine Java-Themen 3
G KeyListener für JTextField Allgemeine Java-Themen 5
webracer999 Library für Textsuche (z. B. include/exclude, and/or)? Allgemeine Java-Themen 5
I Module-Info für Jar erzeugen Allgemeine Java-Themen 7
krgewb Java-Bibliothek für ONVIF Allgemeine Java-Themen 1
B Simpler Eventlistener für Tastaturtaste bauen? Allgemeine Java-Themen 13
_user_q Eingegebenen Text Zeile für Zeile ausgeben lassen Allgemeine Java-Themen 11
E Key für TOTP Algorythmus(Google Authentificator) Allgemeine Java-Themen 0
S Formel für Sonnenwinkel in ein Programm überführen Allgemeine Java-Themen 11
M pfx-Zertifikat in Tomcat für SSL-Verschlüsselung nutzen Allgemeine Java-Themen 14
R Best Practice Erfahrungswerte für eine Migration von JSF nach Angular (oder anderes JS-Framework) Allgemeine Java-Themen 1
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
jhCDtGVjcZGcfzug Klassen Was genau passiert hier? Kann mir das jemand bitte Zeile für Zeile erklären? Allgemeine Java-Themen 1
rosima26 Bester Sortieralgorithmus für kurze Arrays Allgemeine Java-Themen 40
S Mit Methoden kann man definieren für was <T> steht. Geht das auch irgendwie für Variablen? Allgemeine Java-Themen 12
MangoTango Operatoren while-Schleife für Potenz Allgemeine Java-Themen 3
B Lottospiel, genug Reihen tippen für 3 Richtige (Spaß mit Arrays)? Allgemeine Java-Themen 46
B Mit welchen Datentypen und Strukturierung am Besten dutzende Baccaratspiele Shcritt für Schritt durchsimulieren? Allgemeine Java-Themen 26
D Klassendesign für einen Pascal Interpreter Allgemeine Java-Themen 6
I OCR Library für Belegerkennung Allgemeine Java-Themen 7
farah GetterMathod für Farbkanäle Allgemeine Java-Themen 6
B Welcher Datentyp für sehr große Zahlenbereiche? Allgemeine Java-Themen 1
S Webservices für binäre Daten? Allgemeine Java-Themen 5
G Licence-Header für InHouse entwickelten Source Allgemeine Java-Themen 8
M Schleife für einen TicTacToe Computer Allgemeine Java-Themen 5
O git ignore für Intellji braucht es die .idea Dateien? Allgemeine Java-Themen 8
F Java Script für das Vorhaben das richtige? Allgemeine Java-Themen 9
M wiviel Java muss ich für die Berufswelt können ? Allgemeine Java-Themen 5
Robertop Datumsformat für GB ab Java 16 Allgemeine Java-Themen 1
Thallius Verschiedene entities für gleichen Code…. Allgemeine Java-Themen 8
OnDemand Zentrale "Drehscheibe" für verschiedene APIs Allgemeine Java-Themen 14
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
D SHA-3 für Java-version 1.8 Allgemeine Java-Themen 1
N Validator für einen SQL-Befehl Allgemeine Java-Themen 22
Muatasem Hammud Erstellung von Testdaten für Arrays Allgemeine Java-Themen 6
B Logikfehlersuche, das perfekte Lottosystem für 3 Richtige mit Arraylists? Allgemeine Java-Themen 61
G Methoden für die Zukunft sinnvoll? Allgemeine Java-Themen 4
M API für PLZ Umkreissuche Allgemeine Java-Themen 3
1Spinne JDK 8 für Eclipse installieren Allgemeine Java-Themen 5
Tobero Meine Funktion für das beinhalten eines Punktes in einem Kreis funktioniert nicht Allgemeine Java-Themen 5
L Methoden Parser für gängige Datumsformate? Allgemeine Java-Themen 1
H Interface PluginSystem ClassNotFound exception für library Klassen Allgemeine Java-Themen 10
N relativier Pfad für sqlite-Datenbank in Gradle/IntelliJ Allgemeine Java-Themen 2
buchfrau Anagram für beliebiges Wort Allgemeine Java-Themen 2
TonioTec Api für Datenaustausch zwischen Client und Server Allgemeine Java-Themen 0
W Suche Ursache für NPE - woher kommt sie? (Hilfe beim Debugging) Allgemeine Java-Themen 19
Kirby.exe Distanz Map für die Distanztransformation erstellen Allgemeine Java-Themen 1
F PI Regler für Heizung Allgemeine Java-Themen 7
8u3631984 Generelle Log4j.xml für alle Module Allgemeine Java-Themen 5
M Wie übergebe ich den Zähler für die Anzahl Rekursionsschritte korrekt? Allgemeine Java-Themen 2
B Login für User, der im Hintergrund Schedules ausführt Allgemeine Java-Themen 16
L RegEx für Teile einer Berechnung Allgemeine Java-Themen 14
S Java-Task-Management-Tool für Windows und Mac selber programmieren Allgemeine Java-Themen 4
M Java 2D Array für ein Grid erstellen ? Allgemeine Java-Themen 2
Z Welches GUI Framework für Java ist aktuell? Allgemeine Java-Themen 16
N Convert.FromBase64 von C# für Java Allgemeine Java-Themen 11
N fixed-keyword von C# für Java Allgemeine Java-Themen 6
O Suche Scripter für alt:V Project! Allgemeine Java-Themen 0
S Interface Design von HookUp oder Callback Methoden für eigenes Framework Allgemeine Java-Themen 9
O Suche Unterstützung für ein OpenSource-Projekt (grafischer Editor) Allgemeine Java-Themen 13
Kirby.exe Software für Graphische Visualisierung Allgemeine Java-Themen 20
B OOP Auslöser für NullPointerException Allgemeine Java-Themen 3
L Generator für einen Parser implementieren Allgemeine Java-Themen 13
DonMalte Ambitioniertes Projekt für Einsteiger & Motivierte Allgemeine Java-Themen 0
Kirby.exe Movement System für Spiel Allgemeine Java-Themen 13
Kirby.exe Framework für Game Design Allgemeine Java-Themen 8
W Alternative für Threads Allgemeine Java-Themen 6
S Rückgabe einer HttpURLConnection für eine Seite einlesen bei der man eingeloggt ist..? Allgemeine Java-Themen 5
Elyt Compiler-Fehler Datei kann nicht erstellt werden. Die Syntax für den Dateinamen etc. ist falsch. Allgemeine Java-Themen 2
Thallius Rätsel für Windows Profis Allgemeine Java-Themen 8
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
D Input/Output Implementierung eines CommandHandlers/Parsers für viele Eingaben Allgemeine Java-Themen 26
Thallius Alternative für SwingWorker Allgemeine Java-Themen 5
I Lohnt sich heutzutage der Aufwand einer Portierung für MacOS Allgemeine Java-Themen 8
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Datenstruktur für eine Map erstellen Allgemeine Java-Themen 2
H OOP Setting(config) für Applikation sicheren? Allgemeine Java-Themen 9
OnDemand PDF Libary für Formulare Allgemeine Java-Themen 7
S Warmup für Lineare-Suche mit Zeitmessung Allgemeine Java-Themen 2
T Allgemeine Frage: GUI für 3D-Visualisierung Allgemeine Java-Themen 5
M Brainstorming für mein Projekt Allgemeine Java-Themen 30
K OOP Suche Hilfe + Erklärung für eine Hausaufgabe Allgemeine Java-Themen 1
F Was ist der Dateityp meines Parameters für die Main Methode. Allgemeine Java-Themen 6
C Bibliotheken für Algorithmische Geometrie Allgemeine Java-Themen 2
C Daten für Klassifikationsverfahren gewinnen Allgemeine Java-Themen 6
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
I Overlay für Spiele Allgemeine Java-Themen 5
B Suche nach einem Testprogramm für meine BA Allgemeine Java-Themen 0
I GUI für kleine Pop-Ups unter Windows Allgemeine Java-Themen 1
A NetBeans Suche Programmierer für eine Belegarbeit Allgemeine Java-Themen 11
HarleyDavidson Best Practice Wohin mit der Konfigurationsdatei für Desktopapplikationen? Allgemeine Java-Themen 3
R MAC-Adresse eindeutig für einen PC ? Bezug zu Netzwerk, wieso ? Allgemeine Java-Themen 7
N Java API für CardDav und CalDav gesucht Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben