# Eigener Filter mittels FilterReader



## Razzi2007 (22. Mai 2007)

Huhu erstmal!

Da ich neu auf diesem Board bin, weiß ich nicht so Recht, ob meine Frage an dieser Stelle richtig ist. Falls nicht: Sorry!

Aber jetzt mal zu meiner eigentlichen Frage: 

Ich habe aktuell die Aufgabe ein Programm zu schreiben, dass mir einen Text in Caesar Codierung verschlüsselt und entschlüsselt und dabei entweder aus einer .txt Datei liest oder schreibt. 
Soweit eigentlich nicht sonderlich schwer, nur jetzt kommt das "schwierige" daran (zumindest für mich):

Wir sollen dazu 2 eigene Filterklassen Schreiben (*CaesarReader extands FilterReader*) und (*CaesarWriter extands Filewriter*).

Den CaesarWriter habe ich recht zügig hinbekommen und der sieht wie folgt aus und funktioniert auch.


```
package caesar;
import java.io.*;
public class CaesarWriter  extends FilterWriter {
		  
			private int schluessel;
			
			
			public int getSchluessel(){
				return this.schluessel;
			}
			public void setSchluessel(int i){
				this.schluessel = i;
			}
			
			public CaesarWriter(Writer out) { 
				super(out);
				this.schluessel = 1;
				}
			public CaesarWriter(Writer out, int s){
				super(out);
				this.schluessel = s;
			}
			 
			public void write(int c) throws IOException {
					super.write(encrypt((char)c, this.schluessel));
			}

			public void write(char[] cbuf, int off, int len)
			   throws IOException {
			   for (int i = 0; i < len; ++i) {
			   write(cbuf[off + i]);
			   }
			}
			public void write(String str, int off, int len)
			   throws IOException {
			   write(str.toCharArray(), off, len); }
			

			
			public char encrypt(char input, int faktor) {

				// char letter;
				int x = 0;
				int lowerCase = 123;
				int upperCase = 91;
				int addUpper = 65;
				int addLower = 97;
				
				if (faktor > 0
						&& ((input <= 90 && input >= 65) || (input <= 122 && input >= 97))) {

					if (input <= 90 && input >= 65) {

						x = (((int) input + faktor) % upperCase);

						if (x < addUpper)
							x = x + addUpper;

					} else {

						x = (((int) input + faktor) % lowerCase);

						if (x < addLower)
							x = x + addLower;
					}

					input = (char) x;
				}

				return input;
			}

}
```

Soweit so gut. In meinem Hauptprogramm rufe ich das ganze wie folgt auf:



```
String s = "geht Das auch";

		try {
			PrintWriter f = new PrintWriter(new CaesarWriter(
									 new FileWriter("c:\\crypt.txt")));
				
		f.println(s);
		f.close();
		} catch (IOException e) {
		System.out.println("Fehler beim Erstellen der Datei");}}
```

Das funktioniert auch gut, nur kommt jetzt *mein Problem:  Der CaesarReader!*

Der soll so aufgerufen werden:


```
//PrintWriter f;
		String s = "geht Das auch";
		try {
	
			CaesarReader abc = new CaesarReader(new FileReader("c:\\test.txt"),4);
			[b]BufferedReader def = new BufferedReader(abc);[/b]


		char h1 = (char)abc.read();
                                System.out.println(h1);

		[b]System.out.println(def.readLine());[/b]

		def.close();
		} catch (IOException e) {
		System.out.println("Fehler beim Erstellen der Datei");}}
```

Ein einzelnes Zeichen auszulesen und entsprechend dabei zu entschlüsseln, geht ohne Probleme, aber wenn ich mit dem BufferedReader das ganze komplett auslesen will, bekomme ich bei jedem nur erdenklichen Versuch für meine Methode (siehe unten) eine ArrayIndexOutOf BoundsException.  :cry: 

Hier mal der Code meines Reader und die vermeintliche Fehlerstelle habe ich fett hervorgehoben! Diese Methode bekomme ich einfach nicht hin. 


```
package caesar;

import java.io.*;
public class CaesarReader  extends FilterReader {
	  
	private int schluessel;
	private boolean intag = false;
	
	public int getSchluessel(){
		return this.schluessel;
	}
	public void setSchluessel(int i){
		this.schluessel = i;
	}
	
	public CaesarReader(Reader in) { 
		super(in); 
		this.schluessel = 1;
	}
	public CaesarReader(Reader in, int s) { 
		super(in); 
		this.schluessel = s;
	}
	 
	public int read() throws IOException {
	   char[] cbuf = new char[1];
	   int e = super.read();
	   cbuf[0] = (char) e;
	   return (int)decrypt(cbuf[0], this.schluessel);
	}

	

	public int read(int i) throws IOException {
		   char[] cbuf = new char[1];
		   int e = super.read();
		   cbuf[0] = (char) e;
		   return (int)decrypt(cbuf[0], this.schluessel);
		}


	
[b]	public int read(char[] cbuf, int off, int len)
	   throws IOException {

	   for (int i = 0; i < len; ++i) {

	   
	   }
	   return read();
	}[/b]
	
	 
	
	public void read(String str, int off, int len)
	   throws IOException {
		System.out.println("hier");
	   read(str.toCharArray(), off, len);}

	
	public char decrypt(char input, int faktor) {

		int x = 0;
		int lowerCase = 123;
		int upperCase = 91;
		int addUpper = 65;
		int addLower = 97;

		if (faktor > 0
				&& ((input <= 90 && input >= 65) || (input <= 122 && input >= 97))) {

			if (input <= 90 && input >= 65) {

				x = ((int) input - faktor);

				if (x < addUpper)
					x = upperCase - faktor;

			} else {

				x = ((int) input - faktor);

				if (x < addLower)
					x = lowerCase - faktor;

			}
			input = (char) x;

		}
		
		return input;
	}

}
```


Sollte jemand eine Idee haben, wie die Methode *public int read(char[] cbuf, int off, int len)* aussehen muss, wäre ich wirklich sehr dankbar, genauso wie für jede Art von Tipps.

Danke im voraus!!!  :toll:


----------



## kleiner_held (22. Mai 2007)

1. deine Methode read() darf nicht super.read() aufrufen, sondern in.read()  (*in* ist der gekapselte Reader), ausserdem muss sie, wenn die Rückgabe von in.read() == -1 ist, das -1 unverschluesselt zurückgeben.
2. eine Methode read(int i) brauchst du nicht
3. eine Methode read(String str, int off, int len) brauchst du erst recht nicht
4. read(char[] cbuf, int off, int len) müsste so aussehen.

```
public int read(char[] cbuf, int off, int len)
      throws IOException {
      // 1. orginaldaten einlesen
      int result = in.read(cbuf, off, len);
      // 2. dekodieren
      for (int i = 0; i < result; i++)
      {
          cbuf[i+off] = decrypt(cbuf[i+off] ,this.schluessel);
      }
      return result;
   }
```


----------

