PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] Inputstream -> verschiedene Objekte lesen


Gast
2010-06-19, 02:38:37
Hi,
ich habe einen Inputstream von einem HTTP response und möchte nun die Header als String lesen und die eigentlichen Daten in ein byte Array ablegen.

Mein Ansatz sieht wie folgt aus:
InputStream stream = remoteSocket.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));

List<String> requestLines = new ArrayList<String>();
ByteArrayOutputStream message = new ByteArrayOutputStream();

String line;
while ((line = in.readLine()) != null && !line.equals(""))
requestLines.add(line);

byte[] data = new byte[1024];
while (true) {
int len = stream.read(data);
if ( len > 0 )
message.write(data, 0, len);
else if ( len == 0 )
try {
Thread.sleep(20);
} catch (Exception e) {
}
else
break;
}

Das Ergebnis sieht allerdings immer so aus, dass ich nach den Headern nichts mehr bekomme d.h. "stream.read(data)" liefert gleich beim ersten aufruf -1. Also als ob keine Daten mehr vorhanden sind.

Ich verstehe allerdings nicht warum... Wenn ich nach der ersten while Schleife nochmals line = in.readLine() aufrufe, kommt sehr wohl noch was an, und zwar genau das, was ich im ByteArrayOutputStream haben will.

Gast
2010-06-19, 10:31:24
Ich würde sagen es liegt daran, dass der BufferedReader dir stream bereits leer gelesen hat, bevor du direkt auf den Stream zugreifst. Schließlich puffert der BufferedReader etwas und das kann er ja nur wenn er einen großen Brocken auf einmal gelesen hat.

Ich meine mich aber daran zu erinnern das es auch ohne die Verwendung eines BufferedReaders nicht geht. Es ist keine so gute Idee bei der Verwendung eines Decorators (wie bei einem Stream auf Stream, siehe auch [1]) die drunter liegende Componente direkt zu verwenden, da du nicht weißt was für Nebeneffekte der Decorator hat.

[1] http://en.wikipedia.org/wiki/Decorator_pattern

Gast
2010-06-19, 18:47:49
Okay, damit ist wohl der BufferedReader für mein vorhaben ausgeschieden.

Der DataInputStream und ObjectInputStream würden zwar read(byte[]...) und readLine() anbieten (also eigentlich genau das was ich brauche), allerdings ist hier readLine() deprecated.

Hat jemand noch eine gute Idee wie ich am einfachsten mein Vorhaben umsetzen kann, oder bleibt mir nichts anderes übrig als eine readLine() Methode für den normalen InputStream selbst zu schreiben?

robobimbo
2010-06-20, 11:09:19
Du kannst Dir den ganzen Stream in einem Zug auslesen - in ein ByteArray - und von diesem ByteArray aus immer wieder mit einem ByteArrayInputStream einmal deinen Header und einmal deinen Content rauslesen.

Musste ich bei einem TunnelServlet auch mal machen, funktioniert reibungslos.

[edit] Ganz hilfreich sind da auch: http://commons.apache.org/io/

GMP
2010-06-20, 17:23:55
Das Ergebnis sieht allerdings immer so aus, dass ich nach den Headern nichts mehr bekomme d.h. "stream.read(data)" liefert gleich beim ersten aufruf -1. Also als ob keine Daten mehr vorhanden sind.


Da da du den Stream schon paar Zeilen vorher in der while Schleife mit dem BufferedReader leer machst ist das nicht sonderlich überraschend :)