Downloaden einer Datei geht nicht?

Ikaron

Bekanntes Mitglied
Hallo, ich versuch eine Datei herunterzuladen. Das geht zwar, aber wenn ich vorher das timeout umstelle, geht es nicht mehr. Bei Standarttimeout geht es, dieses ist aber null und man kann null nicht als Property setzen, weil man sonst eine nullPointerException bekommt. Ein leerer String ("") geht auch nicht. Wie krieg ich das jetzt hin? Ich hab auch schon versucht die default Properties zu speichern und dann einzusetzen, gibt aber immer nocht den Fehler. Hier ist mein Code:
Java:
public void downloadFile(String url, String outputPath) {

	try {
			
		HttpURLConnection connection = (HttpURLConnection) new URL(url)
			.openConnection();

		connection.connect();
		int size = connection.getContentLength();

		File file = new File(outputPath);
		FileOutputStream fout = new FileOutputStream(file);
		InputStream stream = connection.getInputStream();

		int downloaded = 0;

		while (true) {

			byte buffer[];

			buffer = new byte[size];

			int read = stream.read(buffer);
			if (read == -1)
				break;

			fout.write(buffer, 0, read);

			downloaded += read;

			System.out.println((downloaded / size) + "% (" + downloaded
				+ "/" + size + ")");
		}

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

Error:
Code:
java.net.SocketTimeoutException: Read timed out
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at downloadFile(Codebeispiel:13)
Caused by: java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(Unknown Source)
	at java.io.BufferedInputStream.fill(Unknown Source)
	at java.io.BufferedInputStream.read1(Unknown Source)
	at java.io.BufferedInputStream.read(Unknown Source)
	at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
	at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(Unknown Source)
	at java.net.URLConnection.getHeaderFieldInt(Unknown Source)
	at java.net.URLConnection.getContentLength(Unknown Source)
	at downloadFile(Codebeispiel:8)
	... 1 more
 
Zuletzt bearbeitet:
Mit dieser Beschreibung des Problems kann doch niemand etwas anfangen. 1-2 komplette Sätze und evtl. Codebeispiel oder zumindest Nennung der verwnedeten Klassen/Bibliotheken könnte schon weiterhelfen....
 
Also ich mache das so:

Java:
            URL url = new URL(urlFrom.replace(" ", "%20"));
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.connect();
            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                File targetFile = new File(outputPath);
                FileOutputStream os = new FileOutputStream(targetFile);
                byte buffer[] = new byte[BUFFER_SIZE];
                InputStream is = conn.getInputStream();
                int count = 0;
                long loaded = 0;
                /*
                 * SPEICHERN.
                 */
                while ((count = is.read(buffer)) > 0) {
                    os.write(buffer, 0, count);
                    os.flush();
                }
                os.close();
            }

und habe eigentlich keine Probleme mit download.
😳
 
Wie gesagt, meine Download-Methode geht ja, aber NUR, wenn das timeout vorher nicht gesetzt wurde. Ich teste mal, ob's vllt daran liegt, dass es ein Bild ist.
Edit: Jop, liegt am timeout. Wenn ich das nicht setze, geht aber auch nix, da die Überprüfung blockiert.
 
Zuletzt bearbeitet:
Die im Eingangspost gezeigte Methode läuft - wo ist das Problem? Wurde die in der Zwischenzeit geändert (was ich offen gesagt doof finden würde)

Nur die sysout-Zeile solltest du noch ändern

1.0 damit der Quotient präziser wird und * 100 damit es wirklich % gibt ;-)

Java:
System.out.println((downloaded*1.0 / size)*100 + "% (" + downloaded + "/" + size + ")");
 
Die im Eingangspost gezeigte Methode läuft - wo ist das Problem? Wurde die in der Zwischenzeit geändert (was ich offen gesagt doof finden würde)

Nur die sysout-Zeile solltest du noch ändern

1.0 damit der Quotient präziser wird und * 100 damit es wirklich % gibt ;-)

Java:
System.out.println((downloaded*1.0 / size)*100 + "% (" + downloaded + "/" + size + ")");

Die Prozentanzeige hab ich schon verbessert, nur vergessen es zu posten. Die Methode läuft NICHT, wenn man vorher das Timeout setzt. Das heißt ich habe eine "exists" Methode geschrieben, welche aber ein Timeout benötigt. Dadurch geht der Download nicht mehr.
 
Dein Problem ist, dass zuvor - aus welchen Gründen auch immer - ein Read Timeout gesetzt wurde?
Warum setzt Du es in der Methode nicht einfach hoch auf z.B. 60000ms?

Ansonsten weiss ich nicht ob es so geschickt ist den Buffer zum einlesen auf die Dateigröße zu setzen. Bei kleinen Dateien ist das kein Poblem, aber was ist wenn sie mal ein bißchen größer ist? Da könnte man schnell mal den Rahmen des zur Verfügung stehenden Heap Spaces sprengen!!

Grundsätzlich würde ich die Schleife auch ein bisschen kompakter gestalten.Üblich ist z.B.
Java:
	int downloaded = 0;
	int read;
	byte[] buffer = new byte[100000];
	while ((read = stream.read(buffer)) != -1) {
		fout.write(buffer, 0, read);
		downloaded += read;
		System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
	}
	...
 
Dein Problem ist, dass zuvor - aus welchen Gründen auch immer - ein Read Timeout gesetzt wurde?
Warum setzt Du es in der Methode nicht einfach hoch auf z.B. 60000ms?

Ansonsten weiss ich nicht ob es so geschickt ist den Buffer zum einlesen auf die Dateigröße zu setzen. Bei kleinen Dateien ist das kein Poblem, aber was ist wenn sie mal ein bißchen größer ist? Da könnte man schnell mal den Rahmen des zur Verfügung stehenden Heap Spaces sprengen!!

Grundsätzlich würde ich die Schleife auch ein bisschen kompakter gestalten.Üblich ist z.B.
Java:
	int downloaded = 0;
	int read;
	byte[] buffer = new byte[100000];
	while ((read = stream.read(buffer)) != -1) {
		fout.write(buffer, 0, read);
		downloaded += read;
		System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
	}
	...
Danke für die kleinere Download-Schleife. Ich hab schon das Timeout von zwischen 200ms bis 1000000000ms gesetzt, kein Unterschied, fliegt immer nach ner halben Sekunde, warum auch immer.
 
Danke für die kleinere Download-Schleife. Ich hab schon das Timeout von zwischen 200ms bis 1000000000ms gesetzt, kein Unterschied, fliegt immer nach ner halben Sekunde, warum auch immer.
ne halbe Stunde, wenn ich die Nullen sollte das durchzähle sollte das für mehr als eine halbe Stunde reichen. Wie groß ist denn die Datei und wie schaut es während dessen mit der Ausgabe des Fortschritts aus?
 
ne halbe Stunde, wenn ich die Nullen sollte das durchzähle sollte das für mehr als eine halbe Stunde reichen. Wie groß ist denn die Datei und wie schaut es während dessen mit der Ausgabe des Fortschritts aus?

Kommt nicht bis zum Downloaden, fliegt beim ImputStream raus wegen "ReadTimedOut". Wie gesagt, wenn ich vorher keinen "exists" check mache (Welcher ein Timeout setzt) geht es perfekt. Die Datei is geschätzte 4kB.
 
Zuletzt bearbeitet:
Um das mal zusammen zu fassen hier mal dein "exists" und der Download in einem.
Und bei Dir kommt folgender Code nicht einmal bis zu
Code:
System.out.println("found");
in Zeile 10, wenn Du die Kommentierung in Zeile 6 nicht entfernst?
Bei mir funktioniert der Code ohne Probleme:
Java:
	public static void main(String[] args) {
		try {
			String url = "http://1.1.1.5/bmi/www.java-forum.org/images/misc/java_forum_org.gif";
			String outputPath = "C:/temp/test.gif";
			// System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", "35");
			// System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "35");
			HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
			con.setRequestMethod("HEAD");
			if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
				System.out.println("found");
				HttpURLConnection con2 = (HttpURLConnection) new URL(url).openConnection();
				con2.connect();

				FileOutputStream fout = new FileOutputStream(new File(outputPath));
				InputStream stream = con2.getInputStream();

				int downloaded = 0;
				int size = con2.getContentLength();
				int read;
				byte[] buffer = new byte[100000];
				while ((read = stream.read(buffer)) != -1) {
					fout.write(buffer, 0, read);
					downloaded += read;
					System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
				}
				fout.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
Um das mal zusammen zu fassen hier mal dein "exists" und der Download in einem.
Und bei Dir kommt folgender Code nicht einmal bis zu
Code:
System.out.println("found");
in Zeile 10, wenn Du die Kommentierung in Zeile 6 nicht entfernst?
Bei mir funktioniert der Code ohne Probleme:
Java:
	public static void main(String[] args) {
		try {
			String url = "http://1.1.1.5/bmi/www.java-forum.org/images/misc/java_forum_org.gif";
			String outputPath = "C:/temp/test.gif";
			// System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", "35");
			// System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "35");
			HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
			con.setRequestMethod("HEAD");
			if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
				System.out.println("found");
				HttpURLConnection con2 = (HttpURLConnection) new URL(url).openConnection();
				con2.connect();

				FileOutputStream fout = new FileOutputStream(new File(outputPath));
				InputStream stream = con2.getInputStream();

				int downloaded = 0;
				int size = con2.getContentLength();
				int read;
				byte[] buffer = new byte[100000];
				while ((read = stream.read(buffer)) != -1) {
					fout.write(buffer, 0, read);
					downloaded += read;
					System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
				}
				fout.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

Richtig, wenn ich die Kommentare als Code einsetze geht nix mehr. Als Kommentar geht aber das "exists" nicht, da er ewig wartet bevor er false returnt.
 
Sorry. Selbst wenn ich in folgendem Code die Erhöhung des Timeouts in Zeile 10 auskommentiert läuft es bei mir auf unterschiedlichen Systemen ohne Probleme durch.
Java:
	try {
		String url = "http://www.java-forum.org/images/misc/java_forum_org.gif";
		String outputPath = "C:/temp/test.gif";
		//System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", "500");
		System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "500");
		HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
		con.setRequestMethod("HEAD");
		if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
			System.out.println("found");
			System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "50000");
			HttpURLConnection con2 = (HttpURLConnection) new URL(url).openConnection();
			con2.connect();

			FileOutputStream fout = new FileOutputStream(new File(outputPath));
			InputStream stream = con2.getInputStream();

			int downloaded = 0;
			int size = con2.getContentLength();
			int read;
			byte[] buffer = new byte[100000];
			while ((read = stream.read(buffer)) != -1) {
				fout.write(buffer, 0, read);
				downloaded += read;
				System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
			}
			fout.close();
		}
		else
			System.out.println("HTTP Respone: " + con.getResponseCode());
	} catch (Exception e) {
		e.printStackTrace();
	}
 
😵. Jetzt geht's bei mir auch, warum auch immer. Vielen Dank! Okey, doch nicht, zu früh gefreut. Wieder Read Timed out.
 
Zuletzt bearbeitet:
Sorry. Selbst wenn ich in folgendem Code die Erhöhung des Timeouts in Zeile 10 auskommentiert läuft es bei mir auf unterschiedlichen Systemen ohne Probleme durch.
Java:
	try {
		String url = "http://www.java-forum.org/images/misc/java_forum_org.gif";
		String outputPath = "C:/temp/test.gif";
		//System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", "500");
		System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "500");
		HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
		con.setRequestMethod("HEAD");
		if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
			System.out.println("found");
			System.getProperties().setProperty("sun.net.client.defaultReadTimeout", "50000");
			HttpURLConnection con2 = (HttpURLConnection) new URL(url).openConnection();
			con2.connect();

			FileOutputStream fout = new FileOutputStream(new File(outputPath));
			InputStream stream = con2.getInputStream();

			int downloaded = 0;
			int size = con2.getContentLength();
			int read;
			byte[] buffer = new byte[100000];
			while ((read = stream.read(buffer)) != -1) {
				fout.write(buffer, 0, read);
				downloaded += read;
				System.out.printf("%.1f%% ( %d / %d )\n", (downloaded * 100.0 / size), downloaded, size);
			}
			fout.close();
		}
		else
			System.out.println("HTTP Respone: " + con.getResponseCode());
	} catch (Exception e) {
		e.printStackTrace();
	}

Wenn das Bild aber NICHT existiert, und man DANACH versucht ein existierendes zu downloaden, geht es nicht.
 

Zurück
Oben