Herunterladen von Dateien mit Vergleich

SergiusPro

Mitglied
Hallo! Kann mir, bitte, helfen? Ich versuche mit dem untenstehenden Java-Code ein JPEG-Bild von einer Webseite 4mal herunterzuladen, wobei nach jedem Herunterladen soll geprüft werden, ob das zuletzt gespeicherte Bild mit dem URL-Bild immer noch identisch ist, der Vergleich muss anhand der Dateizeit erfolgen, ist das gespeicherte Bild mit dem URL-Bild identisch, so bekomme ich auch eine Nachricht darüber am Bildschirm und es wird so weiter verglichen, bis das gespeicherte Bild nicht mehr mit dem URL-Bild identisch ist, wo dann erneut heruntergeladen wird, und das Ganze geht von vorne bis 4mal heruntergeladen wurde.

Der Sinn der Sache - auf dem Server wird das Bild in unregelmäßig langen Zeitabständen erneuert und ich möchte nur einmal die aktuellen Bilder herunterladen. Der untenstehende Code speichert aber sofort 4mal nacheinander das gleiche Bild.

Java:
                        for (int counter = 1; counter < 5; counter++)
                        {
                        try
                        {
                            URL url = new URL("http://www.newmexicoskies.com/images/AllSkyImage.jpg");
                            URLConnection uc = url.openConnection();
                            InputStream in = url.openStream();
                            OutputStream out = new BufferedOutputStream(new FileOutputStream(String.format("AllSkyImage%d.jpg", counter)));
                            for (int b; (b = in.read()) != -1; ) {out.write(b);}
                            out.close();
                            in.close();
                            System.out.println(String.format("Image AllSkyImage%d.jpg has been successfully downloaded.", counter));

                            File myFile = new File(String.format("AllSkyImage%d.jpg", counter));
                            File webFile = new File(url.getFile());
                            Long myFileLastModified = myFile.lastModified();
                            Long webFileLastModified = webFile.lastModified();
                            Date myFileDate = new Date(myFileLastModified);
                            Date webFileDate = new Date(webFileLastModified);
                            Long myFileTime = myFileDate.getTime();
                            Long webFileTime = webFileDate.getTime();

                            while (myFileTime == webFileTime){
                            System.out.println(String.format("Saved image AllSkyImage%d.jpg has the same date as the image on the website.", counter));
                            webFile = new File(url.getFile());
                            webFileLastModified = webFile.lastModified();
                            webFileDate = new Date(webFileLastModified);
                            webFileTime = webFileDate.getTime();
                            }
                        }
                        catch (IOException ioe) {System.out.println(ioe.getMessage());}
                        }
 
Zuletzt bearbeitet:

tagedieb

Top Contributor
Du hast da mehrere Designfehler

1. Die Schleife wird 4 mal durchlaufen, dass heisst er laedt und speichert das Image auch 4 mal
2. File.getLastModfied() gibt dir die Systemzeit wann das File bei dir lokal auf dem Rechner zuletzt geaendert wurde.

Loesung.

Du musst die URLConnection in eine HttpURLConnection casten, dann kannst du die Header auslesen. Wenn der Timestamp groesser als dein gecachter Timestampt ist speicherst du den Inhalt.

Das Bild wird aber auf jeden Fall runtergeladen, ausser du sendest einen "HEAD" anstatt eines "GET" request (uc.setRequestMethod("HEAD"); ).
Die "HEAD" Methode sollte dir nur die Headers und nicht das Bild zurueckliefern. Diese Methode wird aber nicht sehr oft unterstuetuezt und er verhaelt sich dann wie ein "GET".

Soweit ich gesehen habe unterstuetzt dein Server die "HEAD" Methode nicht, also wird das Bild immer runtergeladen. Du kannst dann nur noch entscheiden ob du es speichern willst oder nicht.

Java:
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
long timestamp = uc.getHeaderFieldDate("Last-Modified", 0l);
 

SergiusPro

Mitglied
Erstmal danke für die Rückmeldung!

Deine Lösung werde ich gleich ausprobieren, aber erst möchte ich meine Designfehler, auf die du hinweist, nachvollziehen.

1. Die Schleife wird 4 mal durchlaufen, dass heisst er laedt und speichert das Image auch 4 mal

Warum wird denn die Schleife 4 mal durchlaufen? Ich zitiere aus einem Java-Buch, mit dem ich hier Java lerne:

Die while-Schleife beginnt mit der Auswertung eines Ausdrucks und führt den nachfolgenden Block so lange aus, bis die Auswertung des Ausdrucks false ergibt.

Also müsste die Schleife, wie ich's verstehe, so lange "hängen", bis myFileTime != webFileTime zustandekommt. Und erst danach wird counter++ ausgeführt. Ich verstehe also deine Behauptung nicht ganz.

2. File.getLastModfied() gibt dir die Systemzeit wann das File bei dir lokal auf dem Rechner zuletzt geaendert wurde.

Ich wil darauf hinweisen, dass ich in meinem Java-Code nicht die getLastModified()-Methode benutze, die ja nur in der URLConnection-Klasse vorkommt und nicht in der File-Klasse, denn du schreibst hier File.getLastModified(). Die in der File-Klasse enthaltene Methode heißt lastModified(). D.h. ich verstehe nicht, warum du die getLastModified()-Methode überhaupt erwähnst?

Und mal angenommen, wir bleiben bei dem, was ich verwende, nämlich lastModified() – diese Methode, wie du richtig schreibst, liefert die Systemzeit, wann die Datei bei mir lokal auf dem Rechner zuletzt geändert wurde, aber das ist doch genau was ich brauche, um die Zeit meiner lokalen Datei mit der Zeit der URL-Datei zu vergleichen. Wo ist also ein Designfehler hier?
 

SergiusPro

Mitglied
Loesung.

Du musst die URLConnection in eine HttpURLConnection casten, dann kannst du die Header auslesen. Wenn der Timestamp groesser als dein gecachter Timestampt ist speicherst du den Inhalt.

Java:
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
long timestamp = uc.getHeaderFieldDate("Last-Modified", 0l);

Ich habe jetzt deine Lösung ausprobiert. Es hilft mir nicht, es wird immer noch sofort dasselbe Bild 4 mal heruntergeladen. Steckt also der Fehler doch in der while-Schleife? Ich verstehe nicht, was mir da noch felt? Da schreibst du noch über den gecachten Timestamp, ähm, Cache? Ich habe doch mit out.write(b) eine feste JPEG-Datei in denselben Ordner, wo meine Java-Applikation ist, heruntergeladen und will versuchen den 'last-modified"-Parameter dieser Datei (und nicht einer gecachten Datei) mit dem 'last-modified'-Parameter der URL-Datei zu vergleichen.

Mein Java-Code sieht nun (bei der gebliebenen while-Schleife) so aus:

Java:
                        for (int counter = 1; counter < 5; counter++)
                        {
                        try
                        {
                            URL url = new URL("http://www.newmexicoskies.com/images/AllSkyImage.jpg");
                            URLConnection uc = url.openConnection();
                            HttpURLConnection httpuc = (HttpURLConnection) uc;
                            httpuc.connect();
                            InputStream in = url.openStream();
                            OutputStream out = new BufferedOutputStream(new FileOutputStream(String.format("AllSkyImage%d.jpg", counter)));
                            for (int b; (b = in.read()) != -1; ) {out.write(b);}
                            out.close();
                            in.close();
                            System.out.println(String.format("Image AllSkyImage%d.jpg has been successfully downloaded.", counter));

                            File myFile = new File(String.format("AllSkyImage%d.jpg", counter));
                            Long myFileLastModified = myFile.lastModified();
                            Date myFileDate = new Date(myFileLastModified);
                            Long myFileTime = myFileDate.getTime();
                            Long webFileTime = httpuc.getHeaderFieldDate("Last-Modified", 0l);

                            while (myFileTime == webFileTime){
                            System.out.println(String.format("Saved image AllSkyImage%d.jpg has the same date as the image on the website.", counter));
                            webFileTime = httpuc.getHeaderFieldDate("Last-Modified", 0l);
                            }
                        }
                        catch (IOException ioe) {System.out.println(ioe.getMessage());}
                        }
 

SergiusPro

Mitglied
Ups! Bin ich aber doof. :)

Mir fällt erst jetzt ein, dass es doch zwei verschiedene Rechner sind - der meine, wo ich die Bilder speichern will, und der andere, von wo ich die Bilder hole, d.h. die Zeit meines gespeicherten Bildes kann ja gar nicht mit der Zeit desselben Bildes auf dem anderen Rechner gleich sein, grrrrr. Genau deswegen speicherte das Programm NATÜRLICH RICHTIG sofort 4mal nacheinander, denn die Zeit beider Dateien war ja auch nicht identisch.

Also müsste ich jetzt die Aufgabe (und damit auch den Titel dieses Themas) anders formulieren, nämlich, wie vergleiche ich eine heruntergeladene Datei mit einer Web-Datei, von deren URL ich eben diese heruntergeladene Datei habe? Würde das mit getContentLength() gehen? Wie groß ist da die Wahrscheinlichkeit gerade bei JPEG-Dateien, die mit gleichen Einstellungen geschossene Fotos sind, dass zwei verschieden Bilder gleiche Länge haben? Gibt's außer getContentLength() eine andere Eigenschaft, anhand deren man die Dateien sicher vergleichen kann?

Ich versuche gerade volgenden Code, klappt aber trotzdem nicht. Im Code lade ich dasselbe Bild zweimal herunter – einmal unter einem brauchbaren Namen und einmal als Dummy. Dann vergleiche ich die Dateigrößen der beiden, und so lange sie gleich sind, lade ich das Web-Bild wieder und wieder als derselbe Dummy (überschreibt sich) und führe den Vergleich so lange, bis dann die Größen nicht mehr gleich sind, dann kommt counter++ und es wird ein neues Bild heruntergeladen. So sollte es zumindest sein, funktioniert aber nicht, ich kriege wie gehabt propmt dasselbe Bild 4mal heruntergeladen.

Java:
                        for (int counter = 1; counter < 5; counter++)
                        {
                        try
                        {
                            URL url = new URL("http://www.newmexicoskies.com/images/AllSkyImage.jpg");
                            URLConnection uc = url.openConnection();
                            HttpURLConnection httpuc = (HttpURLConnection) uc;
                            httpuc.connect();
                            InputStream in = url.openStream();
                            OutputStream out = new BufferedOutputStream(new FileOutputStream(String.format("AllSkyImage%d.jpg", counter)));
                            OutputStream dummy = new BufferedOutputStream(new FileOutputStream(String.format("dummy%d.jpg", counter)));
                            for (int b; (b = in.read()) != -1; ) {out.write(b); dummy.write(b);}
                            dummy.close();
                            out.close();
                            in.close();
                            System.out.println(String.format("Image AllSkyImage%d.jpg has been successfully downloaded.", counter));
                            System.out.println(String.format("Image dummy%d.jpg has been successfully downloaded.", counter));

                            File myFile = new File(String.format("AllSkyImage%d.jpg", counter));
                            File dummyFile = new File(String.format("dummy%d.jpg", counter));
                            Long myFileLength = myFile.length();
                            Long dummyFileLength = dummyFile.length();

                            while (myFileLength == dummyFileLength){
                            System.out.println(String.format("Saved image AllSkyImage%d.jpg has the same size as the dummy%d.", counter));

                            in = url.openStream();
                            dummy = new BufferedOutputStream(new FileOutputStream(String.format("dummy%d.jpg", counter)));
                            for (int b; (b = in.read()) != -1; ) {dummy.write(b);}
                            dummy.close();
                            in.close();
                            System.out.println(String.format("Image dummy%d.jpg has been successfully downloaded.", counter));
                            myFile = new File(String.format("AllSkyImage%d.jpg", counter));
                            dummyFile = new File(String.format("dummy%d.jpg", counter));
                            myFileLength = myFile.length();
                            dummyFileLength = dummyFile.length();
                            }
                        }
                        catch (IOException ioe) {System.out.println(ioe.getMessage());}
                        }
 
Zuletzt bearbeitet:

tagedieb

Top Contributor
Ich hab jetzt nicht verstanden wieso du nun die Filelaenge vergleichen willst. Es reicht wenn du den "last-modified" header mit dem "last-modified" des letzten image downloads vergleichts. Diesen Wert musst du dir selber speicher und kannst ihn nicht aus deiner lokalen kopie rauslesen.

Ich hab mir das etwa so vorgestellt:


Java:
	long lastModified = 0l;

	public void checkImage(int counter) {
		try {
			// Verbindung zum Server aufbauen und Header informationen lesen
			URL url = new URL(
					"http://www.newmexicoskies.com/images/AllSkyImage.jpg");
			HttpURLConnection uc = (HttpURLConnection) url.openConnection();
			// uc.setRequestMethod("HEAD");
			long timeStamp = uc.getHeaderFieldDate("Last-Modified", 1l);

			// timestamp mit dem timestamp des letzten runtergeladenen Images
			// vergleichen
			// falls ungleich oder der counter auf 0 ist das image runterladen
			if (lastModified != timeStamp) {
				InputStream in = url.openStream();
		                File imageFile = new File(String.format("AllSkyImage%d.jpg",
				counter));
				saveFile(imageFile, in);

				// update lastModified
				lastModified = timeStamp;

				// update application

			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void checkImageLoop() {
		for (int counter = 0; counter < 5; counter++) {
			checkImage(counter);
			try {
				Thread.sleep(1000l * 60 * 5);
				// Image in 5 Minuten intervallen pruefen
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void saveFile(File file, InputStream in)
			throws FileNotFoundException, IOException {
		OutputStream out = new BufferedOutputStream(
				new FileOutputStream(file));

		byte[] buffer = new byte[8192];
		for (int len; (len = in.read(buffer)) != -1;) {
			out.write(buffer, 0, len);
		}
		in.close();
		out.flush();
		out.close();
	}
 

SergiusPro

Mitglied
Danke dir, Tagedieb! Ich war da irgendwie zu doof gewesen, ich hab jetzt alles verstanden und alles funktioniert super, das Programm wird fleißig weiterentwickelt. ;-)

Ich schreibe nämlich ein Programm, mit dem ich weltweit freizugängliche Kameras abfrage und mir Bilder runterlade, um Feuerkugeln (Bolide, sehr helle Meteore) zu überwachen/beobachten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Java applikation herunterladen Java Basics - Anfänger-Themen 10
C File aus dem Internet herunterladen Java Basics - Anfänger-Themen 6
D Webseite zum Herunterladen von Java-Quelltexten? Java Basics - Anfänger-Themen 3
S javadoc herunterladen Java Basics - Anfänger-Themen 2
G Servlet Package wo herunterladen? Java Basics - Anfänger-Themen 2
M Java herunterladen Java Basics - Anfänger-Themen 7
H .java Dateien in Eclipse einbinden und ausführen Java Basics - Anfänger-Themen 1
I Dateien aus dem Resource Folder laden Java Basics - Anfänger-Themen 2
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
Buroto Threads Verschiedene .txt Dateien Auf Listen und Verbinden Java Basics - Anfänger-Themen 3
J Dateien lesen und schreiben Java Basics - Anfänger-Themen 5
B Jar Dateien ohne IDE verwenden? Java Basics - Anfänger-Themen 1
A Optimierung eines Programms: Mergen der Dateien Java Basics - Anfänger-Themen 23
A Zwei XML-Dateien Mergen Java Basics - Anfänger-Themen 14
A Input/Output Mehrere Csv-Dateien einlesen Java Basics - Anfänger-Themen 2
LetsSebi Dateien werden nicht in Zip gespeichert Java Basics - Anfänger-Themen 1
J Alle .java Dateien von einem Verzeichnis in eine Zip speichern Java Basics - Anfänger-Themen 2
J Alle Dateien aus einem Verzeichnis laden Java Basics - Anfänger-Themen 10
MiMa log4j als separate Dateien in Schleife? Java Basics - Anfänger-Themen 6
M Scannen von *.txt - Dateien; wo sind der oder die Fehler? Java Basics - Anfänger-Themen 4
A Input/Output Dateien einlesen und ausgeben Java Basics - Anfänger-Themen 7
S Lese- / Schreibfähigkeit von Dateien sicherstellen Java Basics - Anfänger-Themen 1
C "HelloWorld" - Dateien erstellt, aber ist es eine class-Datei? Java Basics - Anfänger-Themen 2
J Java findet plötzlich die Dateien im Projekt nicht mehr. Java Basics - Anfänger-Themen 12
J Dateien in Verzeichnissen rekursiv auflisten wirft Exception Java Basics - Anfänger-Themen 4
L Classpath Alle Dateien im Classpath finden Java Basics - Anfänger-Themen 4
MiMa Formate für Dateien und Pfade? Java Basics - Anfänger-Themen 1
O Datei in mehrere kleine Dateien umwandeln Java Basics - Anfänger-Themen 47
L Richtige Reihenfolge der Dateien Java Basics - Anfänger-Themen 5
CptK Datentypen Text Dateien einlesen Java Basics - Anfänger-Themen 3
J Logging erzeugt zwei dateien.... Java Basics - Anfänger-Themen 7
A Dateien Verschieben Java Basics - Anfänger-Themen 1
M Mehre Dateien parallel kopieren mit Multithreading Java Basics - Anfänger-Themen 8
C Methoden Dateien im Ordner anzeigen Java Basics - Anfänger-Themen 12
J Java-Dateien lassen sich nicht editieren Java Basics - Anfänger-Themen 46
E FTP Dateien hochladen Java Basics - Anfänger-Themen 3
J Probleme beim schreiben von Dateien Java Basics - Anfänger-Themen 5
Korvinus Vergleichen von 2 csv-Dateien Java Basics - Anfänger-Themen 2
I Texte mit Absätzen in Dateien speichern und auslesen Java Basics - Anfänger-Themen 1
M "substring()" mit Dateien und Pfadangaben Java Basics - Anfänger-Themen 5
Voreck Jar Dateien Standart programm ändern Java Basics - Anfänger-Themen 12
K Dateien aus Source-Package verwenden Java Basics - Anfänger-Themen 10
B Dateien aus dem "resource" - Folder kopieren in Verzeichnis Java Basics - Anfänger-Themen 9
B Kopieren von Dateien mit Adminberechtigungen Java Basics - Anfänger-Themen 14
F Threads ftp4j, viele Dateien upload Java Basics - Anfänger-Themen 5
P Einen Ordner mit Dateien hochladen [FTP] Java Basics - Anfänger-Themen 2
X Dateien direkt hintereinander schreiben, Dateiname Java Basics - Anfänger-Themen 25
G Messwerte in 2 Dateien schreiben Java Basics - Anfänger-Themen 20
C Verarbeitung von sehr großen Dateien Java Basics - Anfänger-Themen 52
F Input/Output Dateien lesen/schreiben Java Basics - Anfänger-Themen 1
V Mehrere Dateien aus JFileChooser in eine ArrayList speichern Java Basics - Anfänger-Themen 2
K Dateien lesen | IndexOutOfBoundsException Java Basics - Anfänger-Themen 2
T Classpath Problem mit dem auslesen von Text-Dateien (Pfad) Java Basics - Anfänger-Themen 3
A attach source: Zusammenhang zwischen JAR und .class/.java Dateien? Java Basics - Anfänger-Themen 2
T .jar Datei als Ordner benutzen/ Dateien aus .jar Datei auslesen Java Basics - Anfänger-Themen 3
C Klassen Class Files nachladen (mehrer .jar Dateien) Java Basics - Anfänger-Themen 2
Bluedaishi for schleife um Dateien wieder zusammen zu fügen Java Basics - Anfänger-Themen 11
S Resourcen-Dateien im Jar-File verfügbar machen (Intellij 14) Java Basics - Anfänger-Themen 14
J Dateien für anderen User "mitgeben" Java Basics - Anfänger-Themen 1
S Dateien mit Java verschieben Java Basics - Anfänger-Themen 6
A Heap Space Error bei rekursiver Suche in Dateien trotz nur einer Zeile im Speicher Java Basics - Anfänger-Themen 26
E Dateien werden nicht gelöscht Java Basics - Anfänger-Themen 10
S Class Dateien decompilieren Java Basics - Anfänger-Themen 4
T Fehler beim Schreiben in Dateien! Java Basics - Anfänger-Themen 4
Bluedaishi Dateien Lassen sich unter windows nicht löschen Java Basics - Anfänger-Themen 8
Z Mehrere XML-Dateien zu einer zusammenfügen Java Basics - Anfänger-Themen 3
K JAR Dateien einbinden - funkt nicht wie es sollte... Java Basics - Anfänger-Themen 22
M Threads nio Dateien kopieren, Threads und Gui Java Basics - Anfänger-Themen 0
J *.sql Dateien in Java Java Basics - Anfänger-Themen 1
P Dateien im Ordner auflisten. Java Basics - Anfänger-Themen 3
P Compiler-Fehler .java Dateien kompilieren und .class Dateien zur .jar Java Basics - Anfänger-Themen 4
S Daten aus anderen Dateien in neue Datei einlesen Java Basics - Anfänger-Themen 3
M Input/Output Arbeiten mit extrem vielen Dateien Java Basics - Anfänger-Themen 8
R File chooser Dateien in frame anzeigen lassen Java Basics - Anfänger-Themen 5
N tar-Dateien Java Basics - Anfänger-Themen 6
B Methoden Dateien konvertieren Java Basics - Anfänger-Themen 3
L Dateien speichern/auslesen Java Basics - Anfänger-Themen 5
M Input/Output Probleme beim Parsen von CSV und TXT Dateien Java Basics - Anfänger-Themen 7
P Wiedereinstieg und kann keine Dateien mehr öffnen... Java Basics - Anfänger-Themen 13
F Classpath Dateien einbinden und Classpath durchsuchen Java Basics - Anfänger-Themen 2
N Java Programm zum Suchen und Ersetzen von Text Dateien Java Basics - Anfänger-Themen 10
S Dateien/LinkedList/StringBuffer - SOrtierung klappt nicht so ganz Java Basics - Anfänger-Themen 2
U Best Practice Nicht-permanente Links auf Dateien Java Basics - Anfänger-Themen 5
B In welchem (Default) Pfad erstellt Java Dateien? Java Basics - Anfänger-Themen 4
I Methoden zum lesen und speichern von Dateien Java Basics - Anfänger-Themen 2
B .ut dateien ignorieren und fortsetzen Java Basics - Anfänger-Themen 9
R Ressourcen in JAR-Dateien Java Basics - Anfänger-Themen 2
J jar Dateien global erreichbar machen Java Basics - Anfänger-Themen 3
L Zusammenführen mehrerer .txt Dateien Java Basics - Anfänger-Themen 4
M Dateien erstellen/ bearbeiten/ lesen Java Basics - Anfänger-Themen 9
S Dateien in RAM kopieren und ausführen? Java Basics - Anfänger-Themen 4
O Java Dateien verschlüsseln? Java Basics - Anfänger-Themen 22
K Unterschied zwischen Jar, war und ear Dateien Java Basics - Anfänger-Themen 3
B Dateien kopieren, entpacken, XML auslesen! Java Basics - Anfänger-Themen 7
B Dateien Verschieben! Java Basics - Anfänger-Themen 8
B ältere Dateien verschieben Java Basics - Anfänger-Themen 3
G Erste Schritte Nach bestimmten Dateien suchen und dann in die Registry schreiben. Java Basics - Anfänger-Themen 6
J Laden von Dateien Java Basics - Anfänger-Themen 19
I Xml dateien zusammenfügen Java Basics - Anfänger-Themen 12
I Dateien in Ordner und Unterordner durchsuchen Java Basics - Anfänger-Themen 18

Ähnliche Java Themen

Neue Themen


Oben