/* 'fileio.java' - IO in Java - (for CPSC 333) */ /* This file explains the use of "streams" and "readers" for IO operations in Java. They are used in socket communications as well as file and console IO. There is a hiearchy of classes that handles IO. At the lowest level are input and output "streams" (e.g. FileInputStream). One commonly used instance (object) of an output stream is "System.out". At the next level there are "readers" and "writers" (e.g. InputStreamReader), which define procedures for IO on stream objects - hence they usually take a stream object in their constructor. These classes are also used for standardization. At the topmost level are classes that provide a convenient interface to the IO operations for programmers - that is, they allow us to use ".readLine()" instead of perhaps reading data character by character. Two very commonly used of these classes are "BufferedReader" and "PrintWriter". The constructors of these classes usually takes streams and lower lever reader/writers as arguments. "PrintWriter" lets you use convient methods such as "println". To set up an object to for IO, you need to create an instance of a class for each level of the hierarchy. A "stream" is in effect a buffer from which data is taken when needed. It is therefore possible to have streams (buffers) that contain items not yet used. This is a very important point to be aware of in network applications. When we write new information to the output stream buffer for a client, sometimes it is necessary to "flush" the buffer - i.e, force the data in the buffer to be sent. Otherwise the client could end up with old data, or data not yet received by the client could be overwritten. All streams and writer classes have a ".flush()" method for this purpose. The following program demonstrates this type of IO with regard to text files. Warning: this style of IO is not the same as the "random access files" which some of you studied in 215. There is no analogy to random access files in networking. */ import java.io.*; // very important line import java.net.*; // used later public class fileio { public static void main(String[] args) { boolean cont = true; // not used String A, B; // some strings for us int lines = 0; // number of lines in input file try { // most IO operations throw exceptions, they need to be caught /* sets up input stream and reader */ FileInputStream fis = new FileInputStream(args[0]); InputStreamReader isr = new InputStreamReader(fis); BufferedReader input = new BufferedReader(isr); /* In the above, "args[0]" is the first command line argument when the program is invoked. Note the sequence of objects needed to create the "BufferedReader". You may of course do this in one line by nesting the constructor calls */ /* sets up output stream and writer */ FileOutputStream fos = new FileOutputStream(args[1]); OutputStreamWriter osw = new OutputStreamWriter(fos); PrintWriter output = new PrintWriter(osw,true); /* The above lines are pretty much analogous to the input case. the "true" argument to the the constructor of "PrintWriter" turns on the "autoflush" option - basically it disables buffering. */ /* the next lines assumes that the first line in the input file is an integer indicating the number of lines to follow. It uses "Integer.parseInt" to convert the String read in into a real integer, which it uses to determine the duration of the for loop. The loop simply copies the lines to the output file */ lines = Integer.parseInt(input.readLine()); for (int i=0;i