InputStream "weiterleiten"

spyboot

Bekanntes Mitglied
Hallo Forum,

Ich habe mir eine kleine InputStream-Klasse geschrieben die später einmal die durch sie laufenden Daten filtern soll. Momentan tut sie leider die Daten nichtmal korrekt weiterleiten. Was ich also möchte ist das genau das was die read()-Methode der übergebenen Klasse zurückgibt auch von dieser Klasse zurückgegeben wird. Einige JPEG-Decoder-Error zeigen aber das es da irgendwo einen Unterschied geben muss.

Java:
import java.io.IOException;
import java.io.InputStream;

import com.sun.corba.se.impl.ior.ByteBuffer;

public class MJPEGDecoder extends InputStream {
	
	InputStream in;
	
	//Hierdrin werden die Zeilen zwischengespeichert
	byte buffer[]=new byte[0];
	
	int bufferReadPos=0;
	
	//Erwartetes Zeichen das das Zeilende markiert
	String lineEnd = "\n";
	byte[] lineEndBytes = lineEnd.getBytes();
	byte[] byteBuf = new byte[lineEndBytes.length];
	
	
	public MJPEGDecoder(InputStream in) {
		this.in=in;
		if(in == null)throw new IllegalArgumentException("InputStream == null");
	}
	
	@Override
	public int read() throws IOException{
		
		while (bufferReadPos==buffer.length) {	
			byte[] line=readLine();
			
			//Hier wird entschieden ob die Zeile in den Buffer kommt
			
			//Zeiger an den Anfang setzen
			bufferReadPos=0;
			//Zeile in den Buffer tun
			buffer=line;
		}
		
		byte b=buffer[bufferReadPos];
		
		bufferReadPos++;
		
		return b;
	}

	
	//Eine Zeile aus dem InputStream lesen
	private byte[] readLine() throws IOException {

		//Ist end true ist das Zeilende erreicht
		boolean end = false;
		
		ByteBuffer b=new ByteBuffer();
		
		while (!end) {
			in.read(byteBuf, 0, lineEndBytes.length);
			
			end=true;
			for(int i=0;i<byteBuf.length;i++){
				
				if(lineEndBytes[i]!=byteBuf[i]){
					end=false;
				}
				
				b.append(byteBuf[i]);
			}
		}
		
		b.trimToSize();
		return b.toArray();
		
	}
	

    public long skip(long n) throws IOException {
    	return in.skip(n);
    }

    public int available() throws IOException {
    	return in.available();
    }

    public void close() throws IOException {
    	in.close();
    }

    public synchronized void mark(int readlimit) {
    	in.mark(readlimit);
    }

    public synchronized void reset() throws IOException {
		in.reset();
    }

    public boolean markSupported() {
		return in.markSupported();
    }
	
}

Danke wie immer für eure Mühe!
 
Zuletzt bearbeitet:

spyboot

Bekanntes Mitglied
Tut mir Leid... aber ich weiß nicht wie mir FilterInputStream da weiterhelfen könnte :bahnhof: Kannst du vll. noch kurz erklären wie er mir bei der Lösung des Problems helfen könnte?
 
S

SlaterB

Gast
zu deinem Programm:
available() liefert in.available(), obwohl du vielleicht noch paar Bytes gecacht hast,
prüfe mit Log-Ausgabe, ob diese Methode aufgerufen wurd,

andere Methoden wie skip/mark sind auch fraglich, wenn möglich lieber gleich Exception werfen

lineEndBytes ist zwei Zeichen lang? wenn alle gelesenen Daten auch immer 'gerade', dann kommt das vielleicht hin,
hast du das getestet?
normalerweise geht man bei Streams nicht auf bestimmte Chars, sondern cacht eine feste Anzahl von Bytes, etwa 100, 500, 1000, oder 2^x,
was spricht dagegen?
schau dir den Quellcode von BufferedInputStream als Inspiration an,
aber deins könnte grob auch funktionieren,

weißt du genauer was alles passiert? loggst du z.B. in deinen read-Methoden welche bytes alle gelesen werden, weißt du welche im Original-Stream drinstehen usw.?
 

FArt

Top Contributor
Wenn du einen Stream schreiben möchtest, der im Prinzip filtert, dann sollte dir das Tutorial weiterhelfen, denn da steht wie man so was macht.

Was ich bei dir nicht verstehe: "MJPEGDecoder" sollte wohl binäre Daten lesen. Du liest aber zeilenweise, was Text entpsricht. Das passt nicht zusammen. Die Bytes werden abhängig vom verwendeteten Encoding u.U. verändert (Bytes werden als Text interpritiert, je nach Encoding u.U. verändert und danach wieder in Bytes verwandelt, dann aber evtl. in andere als ursprünglich).
Lies die Bytes aus dem Stream, dann brennt nichts an.

P.S.: wenn du Stream erweiterst, sollte die Klasse vieleicht auch was mit Stream heißen. Wenn du einen Filter schreibst, solltest du (wie im Tutorial) von der passenden Basisklasse ableiten. Warum verwendest du einen ByteBuffer aus dem CORBA Package?
 
S

SlaterB

Gast
Wenn du einen Stream schreiben möchtest, der im Prinzip filtert, dann sollte dir das Tutorial weiterhelfen, denn da steht wie man so was macht.
also ich sehe auf der von dir verlinkten Seite auch nicht viel mehr als die Aussage
'FilterInputStream ist sinnlos'

inwiefern ist das ein Tutorial?
 

FArt

Top Contributor
also ich sehe auf der von dir verlinkten Seite auch nicht viel mehr als die Aussage
'FilterInputStream ist sinnlos'

inwiefern ist das ein Tutorial?

Ich dachte da war mal ein Beispiel mit drauf... egal...

... aber mit Google und dem Stichwort "FilterInputStream" findet man ganz tolle Beispiele... das nennt man Transferleistung ;-)
 

spyboot

Bekanntes Mitglied
Das Problem ist das der Stream aus Text und Binärdaten besteht:

(?=Zeile ist optional und wird bei einigen Servern gesendet und bei anderen nicht)

Code:
--myboundary
Content-Type: multipart/x-mixed-replace ?
Content-Length: xxxxxxxx ?
?
-JPEG-BILD (binär)
?
--myboundary
--myboundary
Content-Type: multipart/x-mixed-replace ?
...usw

Was der Stream tun soll ist nur das JPEG-Bild weiterzuleiten da der JPEG-Decoder mit dem Text nichts anfangen kann.

Das funktioniert auch ganz gut ohne meine Stream-Klasse wenn ich eine festgelegte Zeilenanzahl überspringe dann den JPEG-Docoder darauf loslasse und wieder eine oder zwei überspringe.
Das Problem ist das ich dafür genau wissen muss wie viele Zeilen der Server nun eigentlich sendet bis er das Bild schickt. Und dafür möchte ich halt noch meinen eigenen Stream dazwischenschalten um die Zeilen zu filtern.

Wenn man sich den Quelltext vom FilterInputStream ansieht merkt man auch schnell das sein Einsatz tatsächlich nicht sonderlich hilfreich wäre da dadurch die Funktion der Klasse nicht groß gewandelt werden würde außer das ich mehr Methoden überschreiben müsste wie zb. read(arg1,arg2,arg3).
 

spyboot

Bekanntes Mitglied
Ich habe wahrscheinlich den Fehler gerade gefunden: Meinem Stream sollte es eig. sch***egal sein ob der "Übergeordnete" (sagt man das eigentlich so?) Stream das Byte -1 sendet oder nicht. die Standartimplementation von read(arg1,arg2,arg3) prüft das aber. Ist mir schon damals aufgefallen also hab ich sie überschrieben. Da dass nichts geholfen hatte habe ich das wieder rückgängig gemacht. Das einzige was ich aber vergessen hatte war auch die dritte read-Methode zu überschreiben. So nun wo das geschehen ist klappt es erst mal. (Ok irgendwie lädt er nur ein Bild und gibt mir dann einen Fehler aus aber ich glaube nicht dass das noch damit zusammenhängt - wenn ich das jetzt auch nicht auf die Reihe kriege ... melde ich mich). Danke für eure Hilfe die mir irgendwie den nötigen Denkanstoß gegeben hat.
 

spyboot

Bekanntes Mitglied
So und der Fehler waaaar.......

So sieht der Code noch aus:

Java:
	@Override
    public long skip(long n) throws IOException {
    	throw new IllegalAccessError("skip not supported");
    }

	@Override
    public int available() throws IOException {
    	return in.available();
    }

	@Override
    public void close() throws IOException {
    	System.out.println("closed");
		//in.close();
    }

	@Override
    public synchronized void mark(int readlimit) {
    	throw new IllegalAccessError("mark not supported");
    }

	@Override
    public synchronized void reset() throws IOException {
    	throw new IllegalAccessError("mark not supported");
    }

	@Override
    public boolean markSupported() {
		return false;
    }

Es wird also angegeben das mark() nicht unterstützt wird.

Aber mark() scheint benötigt zu werden um einen Stream sauber abzuschließen.
Wahrscheinlich ließt der JPEG-Decoder immer noch ein Stück weiter um zu prüfen ob die Binärdaten des Bildes zu ende sind oder nicht und wenn ja setzt er den Stream zurück zum richtigem Ende.
Also packe ich noch mark()-Support rein und das wars. Den mark des übergeordneten Streams konnte ich nicht benutzen da das die Zeilenleserei durcheinander gebracht hätte.

Nochmal ein dickes DANKE an alle!

EDIT: grober Unfug wozu gibt es BufferedInputStream?
 
Zuletzt bearbeitet:

FArt

Top Contributor
???:L

Wenn du mit "grober Unfug" den Inhalt deines Postings meinst, dann hast du Recht.
 
Zuletzt bearbeitet von einem Moderator:

spyboot

Bekanntes Mitglied
Wenn du mit "grober Unfug" den Inhalt deines Postings meinst, dann hast du Recht.

Hast du ein Problem damit dass ich meine Lösung auch anderen zugänglich mache? Ich hätt's auch für mich behalten können dann hätte aber auch nur ich was von gehabt. So verhindere ich dass jemand anderes Stunden in das gleiche Problem steckt.

Edit: @FArt einfach nochmal den Link in deiner Signatur genau durchlesen
 
Zuletzt bearbeitet:
S

SlaterB

Gast
exakt dieselbe Begründung könnte auch FArt für sich geltend machen, falls er eine bessere Lösung kennt,
insofern schon nicht falsch, nur oft viel zu kurz, so dass kaum jemand was damit anfangen kann (also ich auch nicht)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Input/Output InputStream/Scanner(System.in) read()/hasNextLine() block unterbrechen Allgemeine Java-Themen 7
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
W Mal ein paar generelle Fragen zu InputStream und OutputStream Allgemeine Java-Themen 4
L Input/Output InputStream öffnen? Allgemeine Java-Themen 12
P Input/Output Inputstream verhält sich verschieden Allgemeine Java-Themen 9
R Inputstream lesen mit Pointer Allgemeine Java-Themen 0
M InputStream auslesen Allgemeine Java-Themen 1
M String aus InputStream Allgemeine Java-Themen 3
C Threading mit BufferedReader/InputStream & sockets Allgemeine Java-Themen 0
B BufferedWriter in InputStream oder Zeichen-Stream in Byte-Stream Allgemeine Java-Themen 5
P Scanner als Inputstream für Java Prozess Allgemeine Java-Themen 4
E POI-InputStream selber wählen Allgemeine Java-Themen 2
S RandomAcessFile das einen InputStream wrappt..? Allgemeine Java-Themen 2
M Umwandlung ByteArrayOutputStream in InputStream Allgemeine Java-Themen 5
1 InputStream hängt Allgemeine Java-Themen 4
H Input/Output InputStream: 32-Bit-Ganzzahl (DWORD) binär lesen Allgemeine Java-Themen 5
D Datentypen Reader/InputStream wiederverwenden? Allgemeine Java-Themen 11
K Inputstream -> Bilder Allgemeine Java-Themen 23
1 InputStream liest die letzte Zeile nicht ein Allgemeine Java-Themen 2
J Java Datei aus FTP in ein INputstream Allgemeine Java-Themen 2
J InputStream Zip-File Allgemeine Java-Themen 3
F ImageIO cant create InputStream Allgemeine Java-Themen 9
T Integer aus InputStream lesen Allgemeine Java-Themen 3
T Undwandlung eines String in einen InputStream? Allgemeine Java-Themen 3
M Selbst geschriebener InputStreamReader über einen beliebigen InputStream Allgemeine Java-Themen 4
T OutputStream to InputStream Allgemeine Java-Themen 8
S von OutputStream in InputStream schreiben ohne das es blockiert..? Allgemeine Java-Themen 2
reibi BufferedImage nach InputStream Allgemeine Java-Themen 10
R InputStream zweimal lesen Allgemeine Java-Themen 2
G InputStream und File Allgemeine Java-Themen 11
B InputStream zu URL umwandeln Allgemeine Java-Themen 2
F Teile vom InputStream schreiben Allgemeine Java-Themen 9
J InputStream aus URL funktioniert nicht Allgemeine Java-Themen 7
H InputStream Problem mit externem Kommandozeilenprogramm Allgemeine Java-Themen 2
W InputStream öfters nutzen Allgemeine Java-Themen 9
R The mark method of InputStream does nothing. Allgemeine Java-Themen 4
V String oder doch InputStream? Allgemeine Java-Themen 9
A Inputstream in Outputstream umleiten Allgemeine Java-Themen 7
Nils_Langner InputStream soll sich bei neuen Daten melden Allgemeine Java-Themen 2
R InputStream - seltsamer Output Allgemeine Java-Themen 2
S java.io.InputStream.read(byte[] b) überschreiben Allgemeine Java-Themen 33
N InputStream erst ab gegebener Position Allgemeine Java-Themen 4
R InputStream Allgemeine Java-Themen 5
G InputStream kopieren? Allgemeine Java-Themen 6
D Inputstream aus StringBuffer Allgemeine Java-Themen 3
G inputstream() to imageicon() Allgemeine Java-Themen 7
D Durch OutpustStream und InputStream dateien in eine jar sch Allgemeine Java-Themen 3
G aus String einen InputStream erstellen Allgemeine Java-Themen 2
C Wie kann man im InputStream nach einer Zeichenkette suchen? Allgemeine Java-Themen 4
R Aus InputStream wieder eine Datei erzeugen? Allgemeine Java-Themen 2
N String als Inputstream Allgemeine Java-Themen 4
N Suchen in InputStream/ByteArrayOutputStream Allgemeine Java-Themen 11
M InputStream.read abbrechen Allgemeine Java-Themen 2
M Weiterleiten von empfangenen Nachrichten eines StompSessionHandlers Allgemeine Java-Themen 1
E JAVA URL abfangen und weiterleiten? Filter? Allgemeine Java-Themen 6
C Exception weiterleiten bei Abstrakten Methoden ( run ) Allgemeine Java-Themen 10
M Switch von case zu case weiterleiten Allgemeine Java-Themen 6
D Tastaturereignisse weiterleiten Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben