University of North Carolina at Asheville

CSCI 202: Introduction to Data Structures


Lab 03: Input and Output

[Introduction] [Instructions] [What To Submit]


Introduction

This lab will give you a chance to work with some useful features of input and output in Java programming. Note that some of these topics are not covered your text.

Instructions:

To complete this project, follow the steps listed below:

  1. Login to your home directory and launch a terminal window. Use the cd command to change the default directory to csci/202/labs. For the moment, just leave this window lurking around for future reference, and proceed...
  2. Now launch the NetBeans IDE and select the File/New Project... option in the toplevel menu bar. In the first dialog, define the project to be a Java Application. In the second dialog, name your project Lab03, and make sure that your project folder will be created within your csci/202/labs folder. For this lab, you should also uncheck the Create Main Class checkbox. Recall that we do this whenever we want NetBeans to start us off with nothing more than an empty default package for our project. Otherwise, accept the default settings and click Finish.

    If you want to be especially careful, you should now use the file explorer or your terminal window to verify that your Lab03 project folder is indeed in csci/202/labs. While you are doing so, also note that the source files you will be downloading below should all be placed in the project subfolder Lab03/src/. If you discover now or later that a file or folder is not where it should be, please get help from your lab instructor before proceeding further.

  3. Now download the source file RandomSequence.java into your Lab03/src/ folder. Within a few seconds, NetBeans should automatically detect this new file and add it to your Lab03 project.

    Before moving on, you should take the time to list the contents of RandomSequence.java. Hopefully you will have no trouble seeing what this program will do when you run it.

  4. Build the project. This step should cause you no problems, since at this stage you are just compiling an unedited demo program. But if anything goes wrong, check immediately with your lab instructor before proceeding.

    Note that for the next steps, it will not be sufficient merely to compile individual source files. Unfortunately, this is all that happens if you right-click directly on a source file and select the Compile File option. Instead you must be sure to use the project-wide Build option. This compiles all the source files in your project, and it generates a dist subfolder containing a JAR file named Lab03.jar. We will use this JAR file to run project files from the terminal window, as you have already seen in the lectures.

  5. Now switch back to your terminal window, and set your default directory to be the Lab03 subfolder. Use the ls dist command to list the dist folder contents. You should see the file Lab03.jar. If not, it's again time to consult with your lab instructor. You should also enter the command
    > jar tf dist/Lab03.jar
    to examine the contents of Lab03.jar. As you can see, it contains only the bytecode file RandomSequence.class, not the source file RandomSequence.java. But the bytecode is all we need to run this program from a command line.
  6. Enter the command
    > java -cp dist/Lab03.jar RandomSequence 10
    You should recall from the lectures that this command invokes the Java Virtual Machine (JVM) to run a main class called RandomSequence, using the command-line argument 10. The -cp option is used to state that the classpath is just the JAR file Lab03.jar. In general, the classpath is just a list of folders and/or JAR files indicating where RandomSequence or any other referenced classes may be found.

    In any event, you should now be staring at a list of 10 random real values in the terminal window.

  7. Your next task is to make RandomSequence write its output to a textfile, rather than the terminal window. To do this, we simply redefine the standard output device associated with the command you entered above, which by default is just the terminal window. This procedure is called redirection and it can be done for standard input (normally the keyboard) as well as standard output. For output, we simply change the command to
    > java -cp dist/Lab03.jar RandomSequence 10 > results.txt
    which creates a new textfile named results.txt and makes it the standard output for this invocation of RandomSequence. If you now use ls to list the files in your Lab03 folder, you should see that results.txt has been added. You should also use either cat or more to list the contents of results.txt.

    Of course you could choose other names for the output file. You can also supply a complete or relative pathname (not just a base name) to create the file in some other folder. For instance, try

    > java -cp dist/Lab03.jar RandomSequence 10 > ../results2.txt
    and then see if you can find the new file results2.txt.
  8. It is frequently desirable to refine the appearance of data sent to standard output or other output streams. It can be especially useful to know how to format numeric output data. So we will take time out at this stage to revise the source for RandomSequence, to make its output look more like the following:
    
    > java -cp dist/Lab03.jar RandomSequence 5
    5
    0.16548
    0.62123
    0.63176
    0.41656
    0.46035
    
    All it takes to do this is to replace the line
         System.out.println(Math.random());
    by the following:
         System.out.printf("%7.5f\n", Math.random());
    In Java 1.5 and beyond, the standard output stream System.out has a printf() method similar to one developed long ago for C programmers. As used here, this method prints a single random value on a line, just like the println() method call in RandomSequence.java. But printf() prints the value using a format specifier string that specifies the total number of character spaces used to display it (7 in this case), as well as the number of digits shown after the decimal point (5). For future reference, you can find more information on the printf() method and its format specifiers in Chapter 3 of your text (see Section 3.6).

    So make this replacement now, then rebuild the project and run RandomSequence to see the formatted values. We will use the new version for the rest of this lab.

  9. Now we turn to a program that requires data from standard input (which by default is your keyboard). Download the file Average.java into your Lab03/src/ folder. Before you proceed, take a moment to list this program and try to figure out what it does. Then Build your Lab03 project yet again.

    Now return to the terminal window, and enter the command

    > java -cp dist/Lab03.jar Average
    Note that nothing seems to happen at first. That is because this program is waiting for you to provide the standard input stream it is looking for. This will happen only when you start entering data from the keyboard. In this case, you want to supply a sequence of real numbers, separated from each other by whitespace (blanks, tabs, newlines -- but no commas or other punctuation marks). For keyboard input, you will "end" this stream whenever you type ctrl-D (Unix/Linux) or ctrl-C (Microsoft).

    So... enter, say, 5 values, not all on the same line, and then type ctrl-D. What happens at that point?

  10. Next we redirect the standard input stream, so that the list of real numbers needed by the Average program will be read from a textfile rather than the keyboard. Recall that we just happen to have a suitable textfile lying around, namely the file results.txt generated by RandomSequence in a previous step.

    The command to redirect the input is as follows:

    > java -cp dist/Lab03.jar Average < results.txt 
    So enter this command, and the Average program should immediately read all the numbers in results.txt and write its results to standard output (which in this case is the screen again).
  11. In the previous step you saw a case of one program producing output which became the input for a second program. This sort of thing is done so often that Linux and many other operating systems provide a mechanism called piping for "hooking programs together", so that the standard output of one becomes the standard input of another. One simple example of this is the following command:
    > cat results.txt | sort
    The first part of this invokes the cat command, which in this case will list the contents of results.txt to its standard output. This is followed by a vertical bar (|), which represents the pipe that uses this output as standard input to a sort command. As used here, sort treats its standard input as a sequence of lines which it sorts and then passes on to its standard output.

    So enter this command, and see if the results help to clarify all the words you just tried to read...

  12. As a somewhat more long-winded example, try your hand at using the pipe mechanism to have RandomSequence generate 1000 numbers, which Average reads and processes. Let the standard output of Average be the screen, so that when you run this command all you will see is something like the following:

    Number = 1000
    Average = 0.498597009999994

  13. Your final projects in this lab all deal with explicit textfile I/O. These programs create and manipulate their own I/O streams, rather than just using (and possibly redirecting) their standard input and output. These topics are covered in Chapter 9 of your text (see Sections 9.6-9.7).

    To get started, download the following Chapter 9 demos into your Lab03 project:

    TestFileClass.java ReadData.java WriteData.java

    As soon as all these files are in place, open each of them in the NetBeans editor. Read the code and attempt to see what each demo is trying to illustrate. Note in particular that each one starts by creating an instance of java.io.File, which is a Java class representing files on the system. As you can see, each File instance is associated with the name of a file, which can be either a relative filename or an absolute filename (which includes the full pathname).

    Collectively these three demos can show you all you really need to create and manipulate textfiles for many useful applications, so you should take some time to check out their behavior. However, it will be more convenient to you to test these demos if you first modify each one so that its filename is given as a command-line argument rather than a quoted string. For example, in TestFileClass you should change the line

    java.io.File file = new java.io.File ("image/us.gif");
    
    to
    java.io.File file = new java.io.File (args[0]);
    

    After you make these changes, rebuild the project and run TestFileClass from the terminal window with the input argument src:

    
    > java -cp dist/Lab03.jar TestFileClass src
    
    Of course this relative name for the src subfolder in your Lab03 project assumes that your default directory is still csci/202/labs/Lab03.

    Examine the output and verify that you understand everything you see. Then add code that will check whether the named file is actually a directory, and if so have it list all the filenames stored in that directory.

    In the case of ReadData, examine the code and then write your own input textfile of test data for this program to read. Make sure that the program will not encounter any sort of runtime errors due to improper formatting of your data file.

  14. Finally, run WriteData and verify that it indeed creates a new output data file and actually stores data in it. Also check its behavior when you attempt to write to a file that already exists.


What To Submit

When your project is complete and working correctly, demonstrate it to your lab instructor. Then, before you exit NetBeans, clean your Lab03 project. Finally, before you logout, switch back to your terminal and set your default directory back to csci/202/labs. Then create a JAR file of your Lab03 project folder, using the command

> jar cf Lab03Project.jar Lab03
Please leave Lab03Project.jar in your csci/202/labs directory for the remainder of the semester.