// // example program using FileReader, FileWriter, // BufferedReader, BufferedWriter, // and extending FileReader, FileWriter // import java.io.* ; public class TestFilters { // command line arguments are infile, outfile // reads from infile, translates ASCII characters using // rot13 encoding ("rotate" 13 positions), writes results // to standard output, then translates results again and // writes to outfile // resulting outfile should be identical to infile, but // different from output to System.out public static void main(String[] args) { if (args.length < 2) { System.out.println("Two arguments required") ; System.exit(-1) ; } BufferedReader rdr = null ; BufferedWriter wrtr = null ; // input stream is a buffered reader, chained to // an instance of our filter (to do rot-13 // encoding), chained to a file reader whose // source is infile // so input is read from infile, encoded, and // buffered try { rdr = new BufferedReader( new Rot13FilterReader( new FileReader(args[0]))) ; } catch (FileNotFoundException e) { System.out.println("Input file " + args[0] + " not found") ; System.exit(-1) ; } // output stream is a buffered writer, chained to // an instance of our filter (to do rot-13 // encoding), chained to a file writer whose // destination is outfile // so output is buffered, encoded, and written to // outfile try { wrtr = new BufferedWriter( new Rot13FilterWriter( new FileWriter(args[1]))) ; } catch (IOException e) { System.out.println("Output file " + args[1] + " could not be created") ; System.exit(-1) ; } // copy lines from input stream to output stream, // printing to standard output in the process // observe that encoding happens "invisibly" in // our filter streams try { String line = rdr.readLine() ; while (line != null) { System.out.println("Encoded line: " + line) ; wrtr.write(line, 0, line.length()) ; wrtr.newLine() ; line = rdr.readLine() ; } } catch (IOException e) { System.out.println("I/O error during encoding") ; } // closing rdr closes chained input streams too try { rdr.close() ; } catch (IOException e) { System.out.println("I/O error closing reader") ; } // closing wrtr closes chained output streams too try { wrtr.close() ; } catch (IOException e) { System.out.println("I/O error closing writer") ; } } } // // class for filtering (by encoding) character input streams // class Rot13FilterReader extends FilterReader { // must provide constructor to extend FilterReader; // objective is to allow constructing a filter stream // connecting to any character input stream (class Reader) public Rot13FilterReader(Reader r) { super(r) ; // r becomes instance variable "in" // of superclass FilterReader } // override one or more read methods to perform filtering // (we override both to be safe) // note use of read() methods on instance variable "in" to // read from stream we're connected to public int read() throws IOException { return Rot13.rotate(in.read()) ; } public int read(char[] cbuf, int offset, int length) throws IOException { int bytesRead = in.read(cbuf, offset, length) ; if (bytesRead > 0) { for (int i = offset ; i < offset+length ; i++) cbuf[i] = (char) Rot13.rotate(cbuf[i]) ; } return bytesRead ; } } // // class for filtering (by encoding) character output streams // class Rot13FilterWriter extends FilterWriter { // must provide constructor to extend FilterWriter; // objective is to allow constructing a filter stream // connecting to any character output stream (class Writer) public Rot13FilterWriter(Writer w) { super(w) ; // w becomes instance variable "out" // of superclass FilterWriter } // override one or more write methods to perform filtering // (we override both to be safe) // note use of write() methods on instance variable "out" to // write to stream we're connected to public void write(int outChar) throws IOException { out.write(Rot13.rotate(outChar)) ; } public void write(char[] cbuf, int offset, int length) throws IOException { char[] tempbuf = new char[length] ; for (int i = 0 ; i < length ; i++) { tempbuf[i] = (char) Rot13.rotate(cbuf[offset+i]) ; } out.write(tempbuf, 0, length) ; } } // // class for doing rot13 encoding on ASCII text // class Rot13 { static int rotate(int inChar) { int outChar ; if (inChar >= (int) 'a' && inChar <= (int) 'z') outChar = (((inChar - 'a') + 13) % 26) + 'a' ; else if (inChar >= (int) 'A' && inChar <= (int) 'Z') outChar = (((inChar - 'A') + 13) % 26) + 'A' ; else outChar = inChar ; return outChar ; } }