Assignment # 7

File Extravaganza

Due: Wednesday, November 18th by midnight.

Deliverables: Email all files that you create to cis3931@cs.fsu.edu by the due date, including a journal/diary of the steps you went through during this assignment. Since many of the assignments involve writing Java applets it will greatly assist the grading of the assignments if you create HTML on your home page that includes the assignment's applets. Please include the web address of your applet in the journal/diary. Note that for assignments that require you to create source code yourself rather than type in existing code (like this one) you should take careful measures not to accidentally make your .java files world-readable within your HTML directory.

When emailing your files it can be problematic to faithfully re-create the file names. Here are detailed instructions that you can use for this and future assignments. If you use xi.cs.fsu.edu (which is running Solaris) you can create a single compress "tar" file that can then be emailed to cis3931@cs.fsu.edu.

cd location_of_P7_source
gnutar czvf ~/P7.tar.gz .

If you use an email client that supports attachments then you can just attach the file P7.tar.gz to your email submission. If you do not use an email client that supports attachments you will first have to convert the binary compressed "tar" file into a format suitable for an email message, such as uuencoding. Here is an example of encoding the P7.tar.gz file and sending it via a UNIX pipe to a mail client:

uuencode P7.tar.gz < P7.tar.gz | /usr/ucb/mail -s "P7.tar.gz" cis3931@cs.fsu.edu

If you choose to use some other operating system, such as Windows '95, Windows NT or Windows '98 be careful that you use a compression agent that correctly preserves both case sensitivity and the entire file name length, such as WinZip.

You will be asked to re-submit your assignment via email if the format you use is not correctly identified and/or formatted. Please do not email all the files separately.

Assignment:

This assignment covers materials in Lesson 17 (Reading and Writing (but No 'rithmetic)). This lesson covers a large variety of methods found in the java.io package that deal with many types of input/output, such as file I/O. This assignment only demands mastery of a subset of the rich set of classes and methods discussed in this lesson; you are encouraged to become familiar with all of the I/O classes.

The need for different ways of performing almost the same thing (reading and writing data from outside of the program) brings up the desire to measure performance. In this assignment you will create a number of small stand-alone Java applications with which you will run comparison benchmarking tests. You will also explore the wonders of Object Serialization with a small example program.

Data Creation Tools

Before you can write and run your benchmarks, you need two tools that will allow you to easily generate test data. Write two stand-alone Java applications that meet the following specifications:

File Name

Purpose

"Must Use" classes

Notes

createRandomData.java

Generate random bytes of data into an output file (a random byte ranges between the value 0 and 255, inclusive).

File, FileOutputStream

Called via "createRandomData filename num_bytes", where "filename" is the output file name and "num_bytes" is the number of bytes of random data to generate.

createRandomText.java

Generate 80-column random strings of printable ASCII data (printable characters lie in the range of 32 to 126, inclusive).

File, FileOutputStream

Called via "createRandomText filename num_lines", where "filename" is the output file name and "num_lines" is the number of lines of 80-column random text to generate.

Here is a sample execution of these tools that can be used to create random data. The invocation of createRandomData creates a file named "input1" that is 32,768 bytes in size. The invocation of createRandomTextData creates a file named "input2" that is 81,000 bytes in size and that contains 1,000 lines of 80-column text:

xi>java createRandomData input1 32768
xi>java createRandomText input2 1000
xi>ls -l input1 input2
-rw-r--r--   1 jtbauer  fac        32768 Nov  3 13:07 input1
-rw-r--r--   1 jtbauer  fac        81000 Nov  3 13:07 input2
xi:>wc -l input2
    1000 input2

File I/O Benchmark Programs

You are to write seven separate Java stand-alone applications that all accept two filenames on the command line -- the first filename is the name of the input file to be opened and read and the second is the name of the output file to be opened and written. You will find that all these programs are short and have a similar structure (with the exception of the Pipe routines).

File Name

Purpose

"Must Use" classes

Notes

FB.java

Copy input file to output file using a byte stream.

File, FileInputStream, FileOutputStream

FC.java

Copy input file to output file using a character stream.

File, FileReader, FileWriter

bufferedFB.java

Copy input file to output file using a buffered byte stream.

FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream

bufferedFC.java

Copy input file to output file using a buffered character stream.

FileReader, FileWriter, BufferedReader, BufferedWriter

filterDS.java

Copy input file to output file using a popular stream filter.

FileInputStream, FileOutputStream, DataInputStream, DataOutputStream

PB.java

Copy input file to output file using a byte stream through a multi-threaded intermediate pipe.

File, FileInputStream, FileOutputStream, PipedInputStream, PipedOutputStream, Thread

See the example on page 775. Notice for this program you only need one thread for the input file -> pipe input and one thread for pipe output -> output file. Use join() to keep the main thread from exiting before the two worker threads are done.

PC.java

Copy input file to output file using a character stream through a multi-threaded intermediate pipe.

File, FileReader, FileWriter, PipedReader, PipedWriter, Thread

See comment for PB.java

Once you have all these benchmark programs working you are ready to run some tests. First you must have some reliable way to measure the wall clock execution time of these programs. UNIX provides a convenient built-in shell command called time that returns various information about the execution resources a process takes, including wall clock time. As an example, the following two runs demonstrate the use of time to get the execution speeds of the FB program using the random byte data and random text data generated previously:

xi>time java FB input1 output1
0.69u 1.22s 0:02.75 69.4%
xi>time java FB input2 output2
1.28u 3.01s 0:06.65 64.5%

The first number is the number of seconds that the program spent in "user" mode (actually assigned the CPU), where the second number is the time in seconds the program was in "system" or "kernel" mode (executing I/O instructions). The third number is the wall clock time in minutes:seconds. So, in this case, the first instance of FB executed approximately 3 times faster than the second (which makes sense, since file "input2" is almost three times larger than file "input1").

Once you have a reasonable way for measuring time (those working on Windows machines may have to resort to a stop watch :), fill in the following chart and include it in your journal/diary for the program. Make each time value be the average of 5 runs per program name, to lessen the effect that running on a shared machine may cause. Also make sure that you use the same random data file and text file for all seven programs.

Program Name

Time to copy a random data file

Time to copy a random text file

FB

____ seconds

____ seconds

FC

____ seconds

____ seconds

bufferedFB

____ seconds

____ seconds

bufferedFC

____ seconds

____ seconds

filterDS

____ seconds

____ seconds

PB

____ seconds

____ seconds

PC

____ seconds

____ seconds

You should notice how some of the classes perform better than others.

Object Serialization

Finally, the last part of this assignment is to write a small program that demonstrates how Object Serialization works. Write a stand-alone Java application named "serial.java" that uses ObjectInputStream and ObjectOutputStream to read and write an Integer object into a file named "Value". The initial execution of the program will create the "Value" file with the Integer object initialized to the value 1. Subsequent executions of the program will read in the Integer object from the "Value" file, increment the value, write the Integer object back to disk, then print out the new value. Here is a sample execution (notice how the value increments between different invocations of the program).

xi>ls -l Value
Value: No such file or directory
xi>java serial
Current value = 1
xi>ls -l Value
-rw-r--r--   1 jtbauer  fac           81 Nov  3 13:21 Value
xi>java serial
Current value = 2
xi>ls -l Value
-rw-r--r--   1 jtbauer  fac           81 Nov  3 13:21 Value
xi>java serial
Current value = 3
xi>java serial
Current value = 4