Three examples are discussed. The input and output are always from and to a file, but the formats are different.
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
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); } }
In the second example, we read from a file in a binary format, and write it back in an ASCII format.
out.println(in.readInt());
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); } } } }
In the third example, we read from an ASCII table and put the data in an array of doubles.
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.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); } } }