7.3.2 String, Binary and Table Format

Three examples are discussed. The input and output are always from and to a file, but the formats are different.

  1. strings to strings
  2. integers binary to ASCII
  3. ASCII table to array.

From Strings to Strings

We first discuss an example where strings are read from a file, and after some manipulation they are written to an other file. Reading all the lines is done with the readLine method in a while loop. The manipulation of the string consists of first splitting the string in characters, then reversing the order and finally making a string out of the characters again.

Note that

  1. from the input file name, which is read from the first argument, first a FileInputStream is made, then it is given the functionality of a DataInputStream.
  2. For the output stream, we have chosen for a DataOutputStream and not for a PrintStream, although in this case that would have worked as well. The differences between the two classes are twofold: a DataOutputStream will write numeric data in a binary format, while the PrintStream will provide a human readable form. The methods of a DataOutputStream will throw exceptions, while for the PrintStream I/O errors are treated internally and can only be accessed with a special method checkErrors(). This is why in the standard phrase System.out.println you do not have to care about exceptions.
public class Retro {
  
  public static void main (String[] args) {
    if (args.length == 2) {
      try{
	DataInputStream in = new DataInputStream(
	       new FileInputStream(args[0]));
	DataOutputStream out = new DataOutputStream(
	       new FileOutputStream(args[1]));
	revert(in, out);
       } catch (IOException e) {
	System.err.println(e);
       }
    }
    else
      System.err.println("usage: java Retro <inputfile> <outputfile>");
  }
  
  static void revert (DataInputStream in, DataOutputStream out) {
    String line;
    try {
      while ( (line = in.readLine()) != null) {
	out.writeBytes(reverse(line)+'\n');
      } 
    } catch (IOException e) {	
      System.err.println("I/O mistake" + e);
    }
  }

  static String reverse (String s) {
    int len = s.length();
    char[] letters = new char[len];
    char[] reversed = new char[len];
    s.getChars(0, len, letters, 0);
    System.out.print(new String(letters)+" becomes ");
    for (int i=0; i< len; i++)  
      reversed[i] = letters[len - i -1];  
    return new String(reversed); 
  } 
} 

Integers from Binary to ASCII

In the second example, we read from a file in a binary format, and write it back in an ASCII format.

  1. As no manipulation on the data is done, the reading and writing can be contracted into a single line: out.println(in.readInt());
  2. In contrast with the readLine method, the readInt may throw a end-of-file exception. We use that here to break the otherwise infinite loop.
import java.io.*;

public class IntegerBinToASCII  {

  public static void main (String[] args) {
    if (args.length == 2) {
      try {
	DataInputStream in = new DataInputStream(new FileInputStream(args[0]));
        PrintStream out = new PrintStream(new FileOutputStream(args[1]));
	binToASCII(in, out);
      } catch (IOException e) {
	System.err.println(e);
      }
    }    
    else
      System.out.println("usage: java IntegerBinToASCII <inputfile> <outputfile>");
  }

  static void binToASCII (DataInputStream in, PrintStream out) {
    while(true) {
      try {
	out.println(in.readInt());
      } 
      catch (EOFException e) {
	break;
      }
      catch (IOException e) {
	System.err.println(e);
      }
    }
  }
}

ASCII Table to Array

In the third example, we read from an ASCII table and put the data in an array of doubles.

  1. Here the class StringTokenizer is helping us when parsing a line. It splits the line according to the specified separator, and offer methods to pass to the next part, etc.
  2. The data can be visualized with a graph. You can find code for this in PlotFrame.java.
import java.io.*;
import java.awt.*;
import java.util.*;

public class ASCIITableToArray {

  static double[][] points = new double[3][100];
  static DataInputStream data_file;
  static PlotFrame plotFrame;

  public static void main (String[] args) {
    try {
      data_file = new DataInputStream(new FileInputStream(args[0]));
      readArray(points, data_file);
      plotFrame = new PlotFrame(points);
    } catch (Exception e) {
      System.err.println(e);
    }
  }

  static void readArray (double[][] points, DataInputStream in) {
      int i = 0;
      String line;
      try {
	while( (line = in.readLine()) != null) {
	  StringTokenizer token = new StringTokenizer(line, "\t");
	  int j = 0;
	  while (token.hasMoreTokens()) {
	    points[j][i] = Double.valueOf(token.nextToken()).doubleValue();
	    j++;
	  }
	  i++;
	}
      } catch (IOException e) {
	System.err.println(e);
      }
  }
}