HttpInputStream?

Status
Nicht offen für weitere Antworten.
R

ralf2

Gast
`Hi,

Ich würde gern, daten aus internetdaten lesen. Ich weiss aber das die daten die letzten 128 bytes der daten sind.
ich kann zwar einen inputstream öffnen und die daten komplett ziehen
Code:
			URL url = new URL(address);
			out = new BufferedOutputStream(
				new FileOutputStream(localFileName));
			URLConnection  conn = url.openConnection();
			InputStream in = conn.getInputStream();
[\code]
jedoch dauert das zu lange, da die daten meistens größer sind.
kann mir jemand sagen, wie ich z.b. die dateigröße rausfinden kann oder ob ich den InputStream irgendwie casten kann um dann einmal durch zu skippen um so die größe zu bekommen.

bei einem ersten versuch zu einem FileInputStream cast bekam ich:
java.lang.ClassCastException: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream cannot be cast...

kann man die genannte Klasse "HttpInputStream" irgendo bekommen, bzw. gibt es da einen standard von sun. ich nämlich einige packages von diversen anbietern, in eine klasse mit dem namen auftaucht.

mfg ralf
 
R

ralf2

Gast
hi, ich hab es zumindest hinbekommen, durch skippen ans ende zu kommen und die byte richtig zu lesen

Code:
			URL url = new URL(FileAdress);
			conn = url.openConnection();
			in = conn.getInputStream();
			
			long fl= conn.getContentLength();
			long pos= fl-128;
			in.skip(pos);
			byte[] tag= new byte[128];
			in.read(tag);
aber das scheint genausolange zu brauchen, wie als wenn ich die datei lese :cry:
 

Murray

Top Contributor
Das wird per HTTP aus nicht anders gehen- die Länge kannst du zwar in der Regel bereits im Header finden, aber beim Lesen muss der Stream sequenziell Byte für Byte gelesen werden - das HTTP-Protokoll kennt kein "gib mir nur die letzten 128 Byte dessen, was du eigentlich schicken würdest".
 

Murray

Top Contributor
HoaX hat gesagt.:
doch, seit http1.1 gibt es einen range-header
Stimmt, aber damit kann man auch nicht definieren, dass man die letzten 128 einer vorher nicht bekannten Anzahl von Bytes haben will.
Man könnte aber aber evtl. zwei Requests machen: zuerst einen HEAD-Request (also kein GET), um nur den Response-Header zu erhalten und so an das Content-Length-Feld zu kommen. Damit kann man dann die Anfangsadresse berechnen (Content-Length - 128) und dann den GET-Request machen und dabei dann den Range-Header auf diese Anfangsadresse zeigen lassen.
 
R

ralf2

Gast
danke leute, ich taste mich langsam an di lösung heran.

leider gibt es noch schwierikeiten bei mehrfachen zugriff. mache ich z.b.

Code:
			long fl= Long.parseLong(conn.getHeaderField("Content-Length"));
			String req= "byte-range-spec="+String.valueOf(fl-128)+"-";
			conn.addRequestProperty("Range", req);
bekomme ich für die letzte Zeile:

java.lang.IllegalStateException: Already connected.


mh naja auch wenn ich fl schon weiss und fest setze, der request scheint wohl noch nicht ganz richtig zu sein.
 

Murray

Top Contributor
Du musst einen zweiten Request machen; wenn du dir die Content-Length holst, ist der erste Request ja schon zum Server geschickt und beantwortet worden. Danach noch Request-Properties zu setzen, wäre sinnlos (und wird zur Laufzeit mit dieser Exception quittiert).
 
R

ralf2

Gast
ok so klappt es jetzt. obwohl ich conn = url.openConnection(); zweimal aufrufen muss. naja
vielen dank für eure hinweise

Code:
			URL url = new URL(FileAdress);
			conn = url.openConnection();

			long fl= Long.parseLong(conn.getHeaderField("Content-Length"));
//			long fl= 11456683;

			String req= "bytes="+String.valueOf((fl-128)+"-");
			conn = url.openConnection();
			conn.addRequestProperty("Range", req);
			conn.connect();
			//
			in = conn.getInputStream();
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben