# Filter für Input UND OutputStream



## tuxedo (28. Sep 2007)

Hallo,

ich bastle gerade an einer Art Filter. Dieser soll einen OutputStream vor dem Senden auf dem Netzwerk "bearbeiten" und  nach dem empfangen auf der anderen Seite den InputStream wieder in die Ursprungsform vor dem "bearbeiten" zurückverwandeln...

Nochmal anders veranschaulicht:


```
Senden:
OutputStream den die Applikation verwendet ---write---> Filter der den Stream bearbeitet ---write---> OutputStream des Netzwerks

Empfangen:
InputStream des Netzwerks <---read--- Filder der den Stream wieder zurück bearbeitet <---read--- InputStream den die Applikation verwendet
```
Die Problematik liegt jetzt darin, dass ich eigtl nur mit Streams arbeiten möchte. D.h. ich verkette die Streams einfach. Ein Schreibvorgang am einen Ende, zieht sich durch bis zum anderen. Mit dem lesen genau so.

So, ich muss also InputStreams und OutputStreams behandeln können. Dafür möchte ich nicht zwingend Zwei klassen schreiben. Eine Klasse wäre mir am liebsten.

Problem ist: Ich kann ja nur einmal erben, entweder von InputStream oder von OutputStream. 
Hat jemand ne Idee wie ich mit nur einer Klasse beide Fälle abdecke? Über den Konstruktur könnt ich ja sagen "in welche Richtung" es geht. Aber wie stell ich's am geschicktesten an dass meine Filterklasse sowohl den Typ "InputStream" als auch "OutputStream" unterstützt?


----------



## Beni (28. Sep 2007)

Du könntest eine kleine Factory bauen:

Also zuerst sowas:

```
public class Filter{
  public int filter( int x ){
    return ...
  }

  public OutputStream out( OutputStream out ){
    return new FilterOutputStream( out ){
      public void write( int b ){
        super.write( filter( b ));
      }
    }
  }


  public InputStream in( InputStream in ){
    return new FilterInputStream( in ){
      public int read(){
        return filter( super.read() );
      }
    }
  }
}
```

Und später:

```
Filter filter = new Filter();
OutputStream out = ...
out = filter.out( out );
out.write( ... );
```
(FilterInput/OutputStream sind Klassen der Standard-Library)


----------



## tuxedo (28. Sep 2007)

Ja, das wäre meine nächste Lösung gewesen. Und so werd ich's auch  machen. Alles andere verkompliziert den Code nur unnötig.

Danke,

Alex


----------



## tuxedo (28. Sep 2007)

Wenn ich jetzt verschiedene Filter haben möchte, muss ich mir ne Basis schaffen. Was wäre da am geschicktesten? Abstrakte Klasse? Normale Klassen von denen geerbt werden muss? Oder Interfaces? Oder ne Mischung aus beidem?

Bisher sieht's so aus:


```
import java.io.InputStream;
import java.io.OutputStream;

public class Filter {
	
	public Filter(){
		// TODO Hier das FilterSetup machen
	}
	
	public InputStream getInputStream(InputStream in){
		return new InputStreamFilter(in);
	}
	
	public OutputStream getOutputStream(OutputStream out){
		return new OutputStreamFilter(out);
	}

}
```


```
import java.io.IOException;
import java.io.InputStream;

public class InputStreamFilter extends InputStream {

	private InputStream mIn;
	
	/**
	 * vorgelagerten Stream übernehmen
	 * @param in
	 */
	public InputStreamFilter(InputStream in) { 
		mIn = in;
	}

	@Override
	public int read() throws IOException {
		// TODO: lesen von mIn, bearbeiten und dann via return zurückgeben
		return mIn.read();
	}

}
```


```
import java.io.IOException;
import java.io.OutputStream;

public class OutputStreamFilter extends OutputStream {

	private OutputStream mOut;
	
	/**
	 * vorgelagerten Stream übernehmen
	 * @param out
	 */
	public OutputStreamFilter(OutputStream out) {
		mOut = out;
	}

	@Override
	public void write(int b) throws IOException {
		// TODO b bearbeiten und in mOut rein schreiben
		mOut.write(b);
	}

	
	
}
```

Kann mir jemand ein paar Vorschläge machen wie ich die Struktur möglichst geschickt als Basis für verschiedene Filterimplementierungen auslege?

- Alex


----------



## tuxedo (28. Sep 2007)

Ich bin doch selbst auf ne schicke Lösung gekommen:

Hier meine abstrakten Basis-Klassen:

Der Filter an sich:

```
import java.io.InputStream;
import java.io.OutputStream;

public abstract class Filter {
	
	public abstract InputStream getInputStream(InputStream in);
	
	public abstract OutputStream getOutputStream(OutputStream out);

}
```

Und die zu erzeugenden Streams:


```
import java.io.IOException;
import java.io.InputStream;

public abstract class InputStreamFilter extends InputStream {

	private InputStream mIn;
	
	/**
	 * vorgelagerten Stream übernehmen
	 * @param in
	 */
	public InputStreamFilter(InputStream in) { 
		mIn = in;
	}

	@Override
	public int read() throws IOException {
		return process(mIn.read());
	}
	
	protected abstract int process(int b);

}
```


```
import java.io.IOException;
import java.io.OutputStream;

public abstract class OutputStreamFilter extends OutputStream {

	private OutputStream mOut;
	
	/**
	 * vorgelagerten Stream übernehmen
	 * @param out
	 */
	public OutputStreamFilter(OutputStream out) {
		mOut = out;
	}

	@Override
	public void write(int b) throws IOException {
		// TODO b bearbeiten und in mOut rein schreiben
		mOut.write(b);
	}
	
	protected abstract int process(int b);

	
	
}
```

Jetzt muss ich nur für jeden Filter 2 Dinge tun:

1) Für die Filter-Factory von "Filter" erben und in den zwei Methoden die dazu passende implementierung der gefilterten Streams zurückgeben
2) Zwei Klassen erstellen die einmal von "InputStreamFilter" und "OutputStreamFilter" ergeben. Darin reicht's dann einfach die "process" Methode zu implementieren. Fertig... 

Oder hat jemand ne besseren Vorschlag?


----------

