/**-----------------------------------------------------------------------------
* DumbList.java
* Written by Chuck Cusack
* November, 2001
* Modified September, 2005
*-----------------------------------------------------------------------------
* A class that stores a dumb list of integers and floats
* Like most of the code the students hand in, this is "self-documenting".
* As if.
*
* The point of the class is to further demonstrate how to read and write
* both text and binary files.
*
* The list consists of 'listSize' ints and floats.
* There are methods to read and write the list to a file. The format is:
* listSize,theInt[0],theFloat[0],theInt[1],theFloat[1],...
* theInt[listSize-1],theFloat[listSize-1]
* For example, the file could be:
*
* 4 2 2.3443 3 .0000234 10234 1.23 34863496 1234.334
*
* For binary files, there is obviously no spacing between the elements.
* For text files, the items are delimited by spaces, tabs, or newlines.
*
* It is important to realize that in Java, there are several ways of performing
* File I/O. This class presents a few methods of both reading and writing
* to both text and binary files. No claim is made that it is the best way.
*
*
* When you are done looking at this code, you should look at the Java
* API for the following clases:
* // For Text I/O
* FileReader, FileWriter
* PrintWriter
* BufferedReader, BufferedWriter
*
* // For binary I/O
* FileInputStream, FileOutputStream
* DataInputStream, DataOutputStream
*
*-----------------------------------------------------------------------------
*/
import java.awt.*;
import java.io.*;
import java.util.*;
//-----------------------------------------------------------------------------
public class DumbList {
//---------------------------------------------------------------------------
int listSize;
int theInt[];
float theFloat[];
String inputFilename, outputFilename;
char inputType, outputType;
//---------------------------------------------------------------------------
public DumbList() {
theInt=null;
theFloat=null;
}
//---------------------------------------------------------------------------
// A main method to test our class
public static void main(String[] args) {
DumbList A=new DumbList();
A.readInputFilename();
A.readOutputFilename();
A.readFileTypes();
A.ReadList();
A.WriteList();
System.out.println("Done.");
}
//---------------------------------------------------------------------------
public void readFileTypes() {
try {
byte[] filenameArray=new byte[50];
inputType=' ';
while(inputType!='b' && inputType!='t') {
System.out.print("Enter input file type. ");
System.out.print("Output type will be the reverse.\n");
System.out.print("Use 't' for text and 'b' for binary: ");
System.in.read(filenameArray);
inputType=(char) filenameArray[0];
if(inputType=='b') {
outputType='t';
}
else if(inputType=='t') {
outputType='b';
}
}
}
catch(IOException e) {
System.out.println("Don't know what, but something is wrong.");
}
}
//---------------------------------------------------------------------------
public void readInputFilename() {
try {
byte[] filenameArray=new byte[50];
System.out.print("Input Filename: ");
listSize=System.in.read(filenameArray);
inputFilename=new String(filenameArray,0,listSize-1);
}
catch(IOException e) {
System.out.println("Don't know what, but something is wrong.");
}
}
//---------------------------------------------------------------------------
public void readOutputFilename() {
try {
byte[] filenameArray=new byte[50];
System.out.print("Output Filename: ");
listSize=System.in.read(filenameArray);
outputFilename=new String(filenameArray,0,listSize-1);
}
catch(IOException e) {
System.out.println("Don't know what, but something is wrong.");
}
}
//---------------------------------------------------------------------------
public void ReadList() {
if(inputType=='b') {
ReadBinary();
}
else if(inputType=='t') {
ReadText();
}
}
//---------------------------------------------------------------------------
public void WriteList() {
if(outputType=='b') {
WriteBinary();
}
else if(outputType=='t') {
WriteText();
}
}
//---------------------------------------------------------------------------
public void ReadBinary() {
// File I/O can throw nasty exceptions, and they MUST be caught.
// Thus, either the method has to throw the possible exceptions
// that might be generated, or it has to deal with them itself.
// In this case, we deal with it. To do this, we use the regular
// try-catch block.
//
try {
// A few comments in general before we get to the actual code:
//
// Generally when we do File I/O, we use two classes to give us access
// to the file. The first gives us access to the file, and the second
// one gives us convenient methods to write to the file. It looks
// kind of like this:
// DataStream ---> FileStream --> File
// We write to/read from the DataStream (or similar class), which
// writes to the FileStream, which writes to the file.
// This is done for a few reasons:
// 1) It is usually more efficient to use things like DataStreams and
// BufferedReaders/PrintWriters than to write directly to FileStreams
// and FileReaders.
// 2) The DataStreams and BufferedReaders/PrintWriters generally provide
// more convenient methods to perform file I/O.
// Now onto the specifics of this code.
// To begin with, we use a FileInputStream to read from the file.
// This is used when you want to read a file as a binary file.
// As we will see, a FileReader is used for text files.
//
FileInputStream fStream=new FileInputStream(inputFilename);
// We use the DataInputStream wrapped around the FileInputStream
// for efficiency and because it provides nice methods of reading
// primitive types.
//
// It is usual in Java file I/O to use two streams/readers to access
// a file. Generally one gives us access to the file, and the other
// makes doing the I/O faster and/or easier to program.
//
DataInputStream dStream=new DataInputStream(fStream);
// Start by reading in the size of the lists.
listSize=dStream.readInt();
// Now get arrays to store the data.
theInt=new int[listSize];
theFloat=new float[listSize];
// Read the ints and floats.
for(int i=0;i<listSize;i++) {
theInt[i]=dStream.readInt();
theFloat[i]=dStream.readFloat();
}
// Always close a stream when you are done. It's like putting
// the toilet seat down in the bathroom. You might get away
// with it, but it might come back to haught you later...
dStream.close();
}
// Here is where we catch any exceptions that are thrown.
// Notice we only catch an IOException. This is the only
// one we must catch in this case.
catch(IOException e) {
System.out.println("Some File I/O problem occured");
}
}
//---------------------------------------------------------------------------
public void ReadText() {
try {
// Since we are reading a text file, we start by using a FileReader.
FileReader fRead=new FileReader(inputFilename);
// For efficiency and convenience, we wrap the FileReader in a
// BufferedReader. In this case, we read the whole file in as a
// character array, and use a tokenizer to parse it into the data we want.
// This is not the only way to do it, but it works.
BufferedReader bRead=new BufferedReader(fRead);
// We make the (perhaps false) assumption that there are less than
// 1000 characters in the file. Again, there are better ways to do
// this, but for now it will work.
char theInput[]=new char[1000];
// Read the data in.
int numberChars=bRead.read(theInput);
// We can close the file, because we have done all the reading we
// intend to.
bRead.close();
// Get a StringTokenizer based on the input array.
String theData=new String(theInput,0,numberChars-1);
StringTokenizer st=new StringTokenizer(theData," \n\t\r");
// Get the size of the list, which should be the first
// token.
listSize=Integer.parseInt(st.nextToken());
// Get the lists to store the numbers.
theInt=new int[listSize];
theFloat=new float[listSize];
// If there aren't 2*listSize tokens left, there is something
// wrong with the file, so we give up.
if(st.countTokens() != 2*listSize) {
System.out.println("File corrupted.");
}
else {
// Convert the tokens to ints and floats.
for(int i=0;i<listSize;i++) {
theInt[i]=Integer.parseInt(st.nextToken());
theFloat[i]=Float.parseFloat(st.nextToken());
}
}
}
// Here we only catch IOExceptions.
// We should probably also catch NumberFormatExceptions, since
// the Integer.parseInt and Float.parseFloat will throw these
// if the input file is not formatted correctly.
// If this happens, our program will simply crash.
catch(IOException e) {
System.out.println("Some File I/O problem occured");
}
}
//---------------------------------------------------------------------------
public void WriteText() {
try {
// We use a FileWriter since we are writing text.
FileWriter oStream=new FileWriter(outputFilename);
// We wrap the FileWriter with a PrintWriter for efficiency, and
// because, as with the other cases, it provides some nice methods
// for writing primitive types, Strings, and other things.
PrintWriter pWriter=new PrintWriter(oStream);
// We start by writing the size of the list out, including
// the newline character.
pWriter.write(listSize+"\n");
// We then write out the lists. Notice that we must include the
// whitespace when we write, since otherwise the numbers will all
// run together, and then we can't read them back in properly.
for(int i=0;i<listSize;i++) {
pWriter.write(theInt[i]+" "+theFloat[i]+"\n");
}
// As always, we close the writer when we are done.
pWriter.close();
}
catch(IOException e) {
System.out.println("Some File I/O problem occured");
}
}
//---------------------------------------------------------------------------
public void WriteBinary() {
try {
// Hopefully by now, you can figure out what we are doing with the
// two streams. The FileOutputStream and DataOutputStream are useful
// for binary files.
FileOutputStream fStream=new FileOutputStream(outputFilename);
DataOutputStream dStream=new DataOutputStream(fStream);
// We write out the size of the list
dStream.writeInt(listSize);
// We write out the lists. Notice we do NOT include space between
// the numbers, because with binary files, we know the length of each,
// so when we read back in, the data types determines how much data
// to read.
for(int i=0;i<listSize;i++) {
dStream.writeInt(theInt[i]);
dStream.writeFloat(theFloat[i]);
}
// Closing the stream as usual.
dStream.close();
}
catch(IOException e) {
System.out.println("Some File I/O problem occured");
}
}
//---------------------------------------------------------------------------
}