// file: FileExamples.java

import java.io.*;
import java.util.*;

/** Some examples about java.io 
 * @author Jaanus Poial
 * @version 0.6
 * @since 1.5
 */
public class FileExamples {

   /** Main method */
   public static void main (String[] param) {

      //================================================================
      // java.util.Scanner - iterator-type interface
      //================================================================
      System.out.println ("Type integers to sum up (ctrl-D to finish): ");
      Scanner scin = new Scanner (System.in);
      int sum = 0;
      while (scin.hasNext()) {
         sum += scin.nextInt();
      }
      System.out.println ("Sum is: " + sum);

      //================================================================
      // Text input from the keyboard (System.in)
      //================================================================
      System.out.println ("Text input from System.in");
      String s;
      try {
         BufferedReader inp = new BufferedReader
                                   (new InputStreamReader(System.in));
         System.out.print ("Type text: ");
         s = inp.readLine(); // we have one line of text now
         System.out.println ("You typed: " + s);
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }
  
      //================================================================
      // Text output to the file
      //================================================================
      System.out.println ("Text output to the file");
      try {
         PrintWriter outp = 
            new PrintWriter (new FileWriter ("text.txt"), true);
         outp.println ("First line");
         outp.println ("Second line and\nThird line");
         outp.close();
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }

      //===============================================================
      // Text input from the file
      //===============================================================
      System.out.println ("Text input from the file");
      String line;
      try {
         BufferedReader input =
            new BufferedReader (new FileReader ("text.txt"));
         while ((line = input.readLine()) != null) {
            // line read, use it
            System.out.println (line);
         }
         input.close();
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }

      //===============================================================
      // Data output to the file
      //===============================================================
      System.out.println ("Data output to the file");
      try {
         DataOutputStream outpstrm =
            new DataOutputStream (new FileOutputStream ("data.bin"));
         outpstrm.writeInt (1234);
         outpstrm.writeDouble (1.23e4);
         outpstrm.close();
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }

      //===============================================================
      // Data input from the file if the file structure is known
      //===============================================================
      System.out.println ("Data input from the file");
      int n;
      double d;
      try {
         DataInputStream inputstrm =
            new DataInputStream (new FileInputStream ("data.bin"));
         n = inputstrm.readInt();
         d = inputstrm.readDouble();
         inputstrm.close();
         System.out.println ("Result: " + n + " and " + d);
      }
      catch (EOFException e) { // this is important
         System.out.println ("Unexpected end of file: " + e);
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }

      //===============================================================
      // Data input from the file bytewise
      //===============================================================
      System.out.println ("Data input from the file byte by byte");
      int byte1;
      try {
         FileInputStream strm = new FileInputStream ("data.bin");
         System.out.println ("Bytes are: ");
         while ((byte1 = strm.read()) != -1) {
            // byte1 is here, use it
            System.out.print (Integer.toHexString (byte1) + " ");
         }
         strm.close();
         System.out.println();
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }
         
      //===============================================================
      // Read the file into the bytearray
      //===============================================================
      System.out.println ("Read the file into the bytearray");
      byte[] content;
      try { 
         FileInputStream p = new FileInputStream ("text.txt"); 
         content = new byte [p.available()]; 
         p.read (content); 
         p.close(); 
         // content is here, use it
         System.out.write (content);
      } 
      catch (IOException e) { 
         System.out.println ("Input/output error: " + e);
      } 

      //===============================================================
      // Read directory
      //===============================================================
      System.out.println ("Reading directory content");
      String[] dcontent;
      File f = new File (".."); // directory name here
      if (!f.exists() || !f.canRead()) {
         System.out.println ("Not readable: " + f);
         return;
      }
      if (f.isDirectory()) {
         dcontent = f.list(); // content as an array
         for (int i=0; i < dcontent.length; i++)
            System.out.println (dcontent [i]);
      } else {
         System.out.println ("Not a directory: " + f);
      }

      //==============================================================
      // rot13 filter and memory buffer used as a stream
      //==============================================================
      byte [] bfile = null;  // bfile is a byte array

      System.out.println ("Write an encoded file");
      try {
         // baos is an output stream that we convert into an array later
         ByteArrayOutputStream baos = new ByteArrayOutputStream();

         // r13 is an encoded stream that uses baos as a carrier
         Rot13OutputStream r13 = new Rot13OutputStream (baos);
         r13.write ('A');
         r13.write ('B');
         r13.write ('C');
         r13.write ('2');
         r13.write ('n');
         r13.write ('o');
         r13.write ('p');
         r13.write ('.');
         r13.close();

         bfile = baos.toByteArray(); // keep it for other program
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }

   System.out.println ("Encoded file:\n" + new String (bfile));

   System.out.println ("Read and decode");
   int b;
   try {
      Rot13InputStream r13 =
         new Rot13InputStream (new ByteArrayInputStream (bfile));
      System.out.println ("Decoded file: ");
      while ((b = r13.read()) != -1) {
         System.out.print ((char)b);
      }
      System.out.println();
   }
   catch (IOException e) {
         System.out.println ("Input/output error: " + e);
   }

   } // main

} // FileExamples



/** Filter to read from the file and decode. */
class Rot13InputStream extends FilterInputStream {

   Rot13InputStream (InputStream i) {
      super (i);
   }

   public int read() throws IOException {
      return rot13 (this.in.read()); // in is an instance variable
   }

   /** rot13 code - double rot13 gives back the original */
   static int rot13 (int c) {
      if ((c >= 'A') && (c <= 'Z'))
         c = 'A' + (((c - 'A') + 13) % 26);
      if ((c >= 'a') && (c <= 'z'))
         c = 'a' + (((c - 'a') + 13) % 26);
      return c;
   }

} // Rot13InputStream


/** Filter to encode and write to the file. */
class Rot13OutputStream extends FilterOutputStream {

   Rot13OutputStream (OutputStream o) {
      super (o);
   }

   public void write (int c) throws IOException {
      this.out.write (Rot13InputStream.rot13 (c)); 
         // out is an instance variable
   }

} // Rot13OutputStream

// end of file

