# Name der Download-Datei ermitteln



## PRyba (3. Jan 2010)

Ich hab' da ein kleines Problem mit dem Downloaden von Dateien...
URL prüfen, den Stream heraussuchen und in eine lokale Datei übertragen ist nicht das Problem!
Für mich geht's um den Dateinamen!

Beispiel:
Geht man auf die Main-Website von aktuellen Browsern kriegt man
spezielle Links serviert...
um den aktuellen Firefox zu bekommen, klickt man einfach auf...

http://download.mozilla.org/?product=firefox-3.5.6&os=linux&lang=de

Und wenn ich nun solche Links serviert bekomme, und der Download geklappt hat,
wie finde ich dann heraus, wie der Originalname der heruntergeladenen Datei ist/war?

Es gibt Pakete wie Apache HttpClient, die das hinkriegen, aber ich wollte
auf zusätzliche Pakete verzichten...

Hat jemand einen Tipp????:L


----------



## sence (3. Jan 2010)

bietet dir das File, welches du erstellt keine Möglichkeit den Namen heraus zufinden ?


----------



## PRyba (3. Jan 2010)

Mir stehen zwar ein paar Objekte vor und nach dem Download zur Verfügung, aber keines liefert mir den Originalnamen zurück (zumindest soweit ich weiß)....


```
HttpURLConnection
URL
```

Irgendwie muss es doch gehen, oder?!


----------



## sence (3. Jan 2010)

mit welcher Methode bzw Stream lädst du dir das File herunter ?
mir schwebt der gedanke an die Metadaten vor, jenachdem welche Methode / Object / Stream dafür benutzt wird.

kannst du kurz mal den Ausschnitt hier hinein schreiben mit welcher du dir das File holst ?


----------



## PRyba (3. Jan 2010)

Also, hier ist ein Teil des Codes, mit dem ich interessante Daten erhalte und auch die Datei ausgeben kann!


```
URL url = new URL( "http://www.tutego.com/index.html" ); 
HttpURLConnection con = (HttpURLConnection)url.openConnection(); 
System.out.println( con ); 
System.out.println( "Date            : " + new Date(con.getDate()) ); 
System.out.println( "Last Modified   : " + new Date(con.getLastModified()) ); 
System.out.println( "Content encoding: " + con.getContentEncoding() ); 
System.out.println( "Content type    : " + con.getContentType() ); 
System.out.println( "Content length  : " + con.getContentLength() );

url = new URL("http://download.mozilla.org/?product=firefox-3.5.6&os=linux&lang=de");
con = (HttpURLConnection)url.openConnection();
HttpURLConnection.setFollowRedirects(false);
con.connect();

System.out.println(con);
for (String data : con.getHeaderFields().keySet()) {
  System.out.println(data + ": " + con.getHeaderField(data));
}

BufferedReader in = new BufferedReader(
              new InputStreamReader(
               con.getInputStream()));
String inputLine;
		
while ((inputLine = in.readLine()) != null) 
System.out.println(inputLine);
in.close();
		
con.disconnect();
```

Der Code funktioniert bei mir tadelos! Nur finde ich eben nicht heraus wie die Datei heißt, die ich herunterladen KÖNNTE (in diesem Code wird der empfangene Stream einfach auf dem Bildschirm ausgegeben; man kann ihn aber auch problemlos in eine Datei leiten)!

Ich hoffe, dieser Code hilft Euch mir zu helfen!


----------



## Triebi (3. Jan 2010)

Ich hab' mir das mal mit einem DM angesehen.
Bei http://download.mozilla.org/?product=firefox-3.5.6&os=linux&lang=de kommt ein 
	
	
	
	





```
HTTP/1.1 302 Found
```
 zusammen mit 

```
Location: http://mozilla-mirror.3347.voxcdn.com/pub/mozilla.org/firefox/releases/3.5.6/linux-i686/de/firefox-3.5.6.tar.bz2
```
Ich weiß aber, was du meinst, es gibt da noch einen Header dafür...

```
Content-Disposition
```
 könnte es sein, ich finde jedenfalls nix, das besser passt: List of HTTP headers - Wikipedia
Mit dem Firefox-Download hast du dir wohl das falsche Beispiel ausgesucht, aber wahrscheinlich muss eh' auf beide Header-Fields geprüft werden, um den Dateinamen zu bekommen.

PS: Programme & andere Binärdaten solltest du übrigens nicht unbedingt via Buffered*Reader* einlesen. Das gibt nur Unsinn.


----------



## PRyba (4. Jan 2010)

Das ist wirklich interessant...
Normalerweise sollte ich doch mit meinem Java-Code ebenfalls den Location-Header empfangen, aber
stattdessen sieht die Ausgabe für den Firefox-Link plus aller Header-Daten so aus:


```
sun.net.www.protocol.http.HttpURLConnection:http://download.mozilla.org/?product=firefox-3.5.6&os=linux&lang=de
null: HTTP/1.1 200 OK
ETag: "2fa06-938584-479b89e712080"
Content-Language: pt
Date: Mon, 04 Jan 2010 12:35:17 GMT
Content-Length: 9667972
Last-Modified: Wed, 02 Dec 2009 06:02:26 GMT
Keep-Alive: timeout=2, max=100
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Type: application/x-bzip2
Server: Apache
```

Schaffst Du's mit Java-Code an den Location-Header zu kommen? Wenn ja, dann wär das schon mal ein wichtiger Einstiegspunkt für mich!

Die Liste der HTTP Header bin ich auch schon durch... muss aber zugeben, dass ich bisher 
	
	
	
	





```
Content-Disposition
```
 außen vor gelassen habe. Danke für den Tipp!

Und was den BufferedReader angeht, hast Du natürlich Recht...
in meinem "richtigen" Code schick' ich den InputStream direkt in ein RandomAccessFile! Klappt super damit!

Thx für die bisherige Hilfe... ich hoffe, Du kannst mir noch den entscheidenden Tipp liefern!?


----------



## eso (4. Jan 2010)

Du musst an den HTTP 302 ran kommen. Ich weiss jetz nicht ob dein 
	
	
	
	





```
HttpURLConnection.setFollowRedirects(false);
```
 funktioniert. Ich mache es mit 

```
conn = (HttpURLConnection)url.openConnection();
conn.setInstanceFollowRedirects(false);
```
Damit solltest du nicht automatisch weiter geleitet werden, sondern kannst die "Location" abfragen. Etwa so:

```
if(conn.getResponseCode()==302 || conn.getResponseCode()==301)
		        {
		        	String newUrl=conn.getHeaderField("Location");
		        	if(newUrl.startsWith("/"))
		        	{
		        		newUrl=url.getProtocol() + "://" + url.getHost() + newUrl;
		        	}

		        	this.url=new URL(newUrl);

		        }
```
Das ganze muss in eine Schleife, da man u.U. mehrmals weitergeleitet wird


----------



## PRyba (4. Jan 2010)

Du hast einen Volltreffer gelandet... Herzlichen Dank!

Die globale Methode von HttpURLConnection zeigt keinen Effekt...


```
HttpURLConnection.setFollowRedirects(false);
```

aber die Methode für Instanzen klappt problemlos bei diesen Links


```
conn = (HttpURLConnection)url.openConnection();
conn.setInstanceFollowRedirects(false);
```

Das war der entscheidende Hinweis!!! Kollege, du bist ein Genie!

Im Grunde würde ich das Thema abschließen, aber mich interessiert noch ob das normal ist, dass die Instanzmethode funktioniert, aber nicht die statische Methode, die eigentlich für sämtliche HttpURLConnection-Objekte gelten sollte!

Oder ist es ein Bug?!

P.S.: Auch einen Dank an alle anderen, die zur Lösungsfindung beigetragen haben!


----------

