Big Java / Java Concepts Lab 16

Reading and Writing Text Files

1.

Write a program to store multiple memos in a file. Allow a user to enter a topic and the text of a memo (the text of the memo is stored as a single line and thus cannot contain a return character). Store the topic, the date stamp of the memo, and the memo message.

Use a text editor to view the contents of the "memo.dat" file and to check that the information is stored correctly.

Creating a java.util.Date object with no arguments will initialize the Date object to the current time and date. A date stamp is obtained by calling the Date.toString() method.

Part of the code of the program has been provided for you:

import . . .

public class MemoPadCreator
{
   public static void main(String args[])
   {
      Date now;
      Scanner console = new Scanner(System.in);
      System.out.print("Output file: ");
      String filename = console.nextLine();

      try
      {
         PrintWriter out = . . .;

         boolean done = false;
         while (!done)
         {
            System.out.println("Memo topic (enter -1 to end):");
            String topic = console.nextLine();
            if (topic.equals("-1"))
               done = true;
            else
            {
               System.out.println("Memo text:");
               String message = console.nextLine();
               /** Create the new date object and obtain a dateStamp */

               out.println(topic + "\n" + dateStamp + "\n" + message);
            }
         }
         /** Close the output file*/
     
}
      catch (. . .)
      {
         . . .
      }
   }
}

What is the code for your program?


2.

Modify your memo writing program to read multiple memos stored in a text file. Memos are stored in three lines. The first line is the memo topic, the second line is the date stamp, and the third line is the memo message. Display the memos one at a time, and allow the user to choose to view the next memo (if there is one).

Part of the program code has been provided for you:


. . .

public class MemoPadReader
{
   public static void main(String[] args)
   {
      Scanner console = new Scanner(System.in);
      System.out.print("Input file: ");
      String inputFileName = console.nextLine();

      try
      {
         FileReader reader = . . .;
         Scanner in = new Scanner(reader);

         boolean done = false;
         while (in.hasNextLine() && !done)
         {
            String topic = . . .;
            String dateStamp = . . .;
            String message = . . .;
            System.out.println(topic + "\n" + dateStamp + "\n" + message);

            if (. . .) // You should only ask to display the next memo if there are more memos in the file
            {
               System.out.println("Do you want to read the next memo (y/n)?");
               String ans = console.nextLine();
               if (ans.equalsIgnoreCase("n"))
               done = true;
            }
         }

         reader.close();
      }
      catch (. . .)
      {
         . . .
      }
   }
}

What is the code for your program?



3.

Modify your simple memo reader program. Use the JFileChooser to allow the user to choose the file from which the memos will be read.

You can use the showOpenDialog method to enable the user to select a file to "open". This method returns either JFileChooser.APPROVE_OPTION, if the user has chosen a file, or JFileChooser.CANCEL_OPTION, if the user canceled the selection.

If a file was chosen, then you call the getSelectedFile method to obtain a File object that describes the file. Here is a complete example:

JFileChooser chooser = new JFileChooser();
FileReader in = null;
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
   File selectedFile = chooser.getSelectedFile();
   reader = new FileReader(selectedFile);
   . . .
}

What is the code for your program?

File Encryption


4.

Write a program that encrypts (or decrypts) a file using an XOR cipher. An XOR cipher encrypts a byte by performing an XOR bitwise operation with the byte to be encrypted and a key. In Java, you can perform bitwise XOR using the ^ operator.

First, write a class XorEncryptor that encrypts or decrypts a file using an XOR cipher. Part of the code of the class has been provided for you:

import . . .

/**
   An encryptor encrypts files using a "XOR" cipher.
*/
public class XorEncryptor
{
   /**
      Constructs an encryptor.
      @param aKey the encryption key
   */
   public XorEncryptor(byte aKey)
   {
      key = aKey;
   }

   /**
      Encrypts the contents of a file.
      @param inFile the input file
      @param outFile the output file
   */
   public void encryptFile(String inFile, String outFile)
      throws . . .
   {
      InputStream in = null;
      OutputStream out = null;

      try
      {
         in = . . .;
         out = . . .;
         encryptStream(in, out);
      }
      finally
      {
         /** Close the files */
      }
   }

   /**
      Encrypts the contents of a stream.
      @param in the input stream
      @param out the output stream
   */
   public void encryptStream(InputStream in, OutputStream out)
      throws . . .
   {
      boolean done = false;
      while (!done)
      {
         int next = . . .;
         if (next == -1) done = true;
         else
         {
            byte b = (byte) next;
            byte c = encrypt(b);
            out.write(c);
         }
      }
   }

   /**
      Encrypts a byte.
      @param b the byte to encrypt
      @return the encrypted byte
   */
   public byte encrypt(byte b)
   {
      return . . .;
   }

   private byte key;
}

What is the complete code for the XorEncryptor class?


5.

Write a tester program that asks the user for the name of a file to encrypt (or decrypt) and the name of the output file, and encrypts (or decrypts) the file. Note that both operations are performed in exactly the same way. Your program should also ask the user for the encryption key to use.

What is the complete code for your tester class?


6.

Test your program. Create a file with the following content and encrypt it. Use "a" as the encryption key.

This is a test for the XOR encryptor.

Open the encrypted file with a text editor. What are the contents of the encrypted file?


7.

Decrypt the file you just encrypted using your program. Don't forget to use "a" as the decryption key. What is the output?

Command Line Arguments


8.

Modify your testing program so that the input file, output file, and encryption key are supplied on the command line.

What is the code for your modified tester class?


9.

What command do you use to run your program to encrypt the file message.txt into the file message.enc, using a as the encryption key? What command do you use to decrypt the message.enc file?

Random Access Files

10.

Create a program that reads and stores memos in a RandomAccessFile. To be able to read and write memos in a random access file, the topic, date stamp and message should each have a fixed size.

First, complete the code for the class MemoPad. You will write the tester program in the next problem.


public class MemoPad
{
   public MemoPad()
   {
      file = null;
   }

   public void open(String filename) throws IOException
   {
      . . .
   }

   /**
      Gets the number of memos in the file.
      @return the number of memos
   */
   public int size() throws IOException
   {
      . . .
   }

   public void close() throws IOException
   {
      if (file != null) file.close();
      file = null;
   }

   /**
      Reads a memo record. The values of the last record read can be obtained
      with the getTopic, getDateStamp and getMessage methods.
      @param n the index of the memo in the file
   */
   public void read(int n) throws IOException
   {
      file.seek(. . .);
      byte[] topic = new byte[MAX_CHARS_TOPIC];
      byte[] date = new byte[MAX_CHARS_DATE];
      byte[] message = new byte[MAX_CHARS_MSG];
      /* Read the topic, date and message from the file (use the method "read(byte[])".
         Then, convert the byte arrays to strings and store them in the variables currentTopic,
         currentDateStamp and currentMessage
      */
   }

   public String getTopic()
   {
      return currentTopic; // returns the topic of the last memo read
   }

   public String getDateStamp()
   {
      return currentDateStamp;
   }

   public String getMessage()
   {
      return currentMessage;
   }

   public void write(int n, String topic, String dateStamp, String message) throws IOException
   {
      file.seek(. . .);

      file.writeBytes(. . .); // "topic" should have a fixed size
      file.writeBytes(. . .); // "dateStamp" should have a fixed size
      file.writeBytes(. . .); // "message" should have a fixed size
   }

   /**
      Adds white spaces to a string or cuts the string, so the string has a length of exactly "size".
      @param str the input string
      @param size the desired size
      @return the new string
   */
   private String padOrTrim(String str, int size)
   {
      if (str.length() < size)
      {
         String pad = "";
         for (int i = str.length(); i < size; i++)
         pad = pad + " ";
         return str + pad;
      }
      else
         return str.substring(0, size);
   }

   private RandomAccessFile file;
   private String currentTopic;
   private String currentDateStamp;
   private String currentMessage;

   public static final int MAX_CHARS_TOPIC = 25;
   public static final int MAX_CHARS_DATE = 40;
   public static final int MAX_CHARS_MSG = 250;
   public static final int RECORD_SIZE = MAX_CHARS_TOPIC + MAX_CHARS_DATE
      + MAX_CHARS_MSG;
}

What is the complete code for this class?



11.

Write a tester program that allows the user to add or display a memo. Memos should be added to the end of the file. If the user wants to display a memo, a list of the existing topics should be provided, so that the user can select which one he/she wants to see. Complete the following program:


public class MemoPadTester
{
   public static void main(String args[])
   {
      Scanner console = new Scanner(System.in);
      System.out.println("Input file:");
      String filename = console.nextLine();

      try
      {
         MemoPad memoPad = new MemoPad();
         memoPad.open(. . .);

         boolean done = false;
         while (!done)
         {
            System.out.print("Enter A to add a memo, D to display an existing memo or Q to quit: ");
            String choice = console.nextLine();

            if (choice.equalsIgnoreCase("A"))
            {
               System.out.println("Topic (max 25 characters):");
               String topic = console.nextLine();
               String dateStamp = (new Date()).toString();
               System.out.println("Message (max 250 characters):");
               String message = console.nextLine();
               memoPad.write(. . ., topic, dateStamp, message);
            }
            else if (choice.equalsIgnoreCase("D"))
            {
               if (memoPad.size() > 0)
               {
                  // Display the list of topics
                  for (int i = 0; i < . . .; i++)
                  {
                     memoPad.read(. . .);
                     System.out.println(i + " " + . . .);
                  }

                  System.out.println("Enter the number of the memo to display:");
                  int n = Integer.parseInt(console.nextLine());
                  memoPad.read(. . .);
                  System.out.println(. . .); // topic
                  System.out.println(. . .); // date stamp
                  System.out.println(. . .); // message
               }
               else
               {
                  System.out.println("There are no memos in the file.");
               }
            }
            else if (choice.equalsIgnoreCase("Q"))
               done = true;
         }
         memoPad.close();
      }
      catch (IOException exception)
      {
         System.out.println("Input/output error: " + exception);
      }
   }
}

What is the complete code for this class?

Object Streams

12.

Write a program that writes memos to a file as object streams.The Memo class should have fields to store a topic, a date stamp and the memo message. Allow a user to enter multiple memos, supplying the topic and message. Your program should provide the date stamp using the java.util.Date object. (Creating a Date object with no arguments initializes the object to the current time and date).

Let the user choose the file name to which the memos are saved.

What is the code for your Memo class? Remember to implement the Serializable interface!



13.

Provide a tester program for your Memo class. Allow a user to enter multiple memos, supplying the topic and message. Your program should provide the date stamp using the java.util.Date object (creating a Date object with no arguments initializes the object to the current time and date). Let the user choose the file name to which the memos are saved.


After saving the file, your tester program should open the file and print out all memos.

You can modify the program you created in problem 1.

What is the code for your tester program?