Weiter | Weiter | Weiter | Weiter | Kommentar

all-inOne, section 17.

17.  I/O: Files and Streams

See also: http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/package-summary.html

File:

In Java, file I/O as well as keyboard/screen I/O is handled by streams.

17.1.  Overview

17.2.  Input Stream

For an input stream, the source of data might be a file, a String, an array of bytes, or bytes written to an output stream (typically by another thread). There are also "filter input streams" that take data from another input stream and transform or augment the data before delivering it as input. For example, a DataNumberInputStream passes bytes through verbatim but counts line terminators as they are read.

The drawings have been created by Charles L. Perkins.

17.3.  Output Stream

For an output stream, the sink of data might be a file, an array of bytes, or a buffer to be read as an input stream (typically by another thread). There are also "filter output streams" that transform or augment data before writing it to some other output stream.

An instance of class File represents a path name (a String) that might identify a particular file within a file system. Certain operations on the file system, such as renaming and deleting files, are done by this class rather than through streams.

17.4.  Using Streams

No matter where the information is coming from or going to the algorithm for reading/writing is pretty much always the same:

Reading:

open a stream for reading
while more information
     read
     process

close stream

Writing:

open a stream for writing
while more information
     process
     write

close stream

17.5.  File Descriptor

An instance of class FileDescriptor represents an abstract indication of a particular file within a file system; such file descriptors are created internally by the Java I/O system.

Methods:

public native boolean valid()

Tests if this file descriptor object is valid. Returns: true if the file descriptor object represents a valid, open file or socket; false otherwise.
sync

Force all system buffers to synchronize with the underlying device. This method returns after all modified data and attributes of this FileDescriptor have been written to the relevant device(s). In particular, if this FileDescriptor refers to a physical storage medium, such as a file in a file system, sync will not return until all in-memory modified copies of buffers associated with this FileDesecriptor have been written to the physical medium.

The Solaris man page:

sync() causes all information in memory that should be on disk to be written out. This includes modified super blocks, modified i-nodes, and delayed block I/O.

It should be used by programs that examine a file system, such as fsck.1m df.1m etc. It is mandatory before a re-boot.

The writing, although scheduled, is not necessarily completed before sync() returns. The fsync function completes the writing before it returns.

17.6.  Data Processing Streams

Processing streams perform some sort of operation, such as buffering or character encoding, as they read and write. Like the data sink streams, java/io often contains pairs of streams: one that performs a particular operation during reading and another that performs the same operation (or reverses it) during writing. This table gives java/io's processing streams

---------------------+--------------------+-----------------------
Process              | Character Stream   | Byte Stream
---------------------+--------------------+-----------------------
Buffering            | BufferedReader,    | BufferedInputStream,
                     | BufferedWriter     | BufferedOutputStream
---------------------+--------------------+-----------------------
Filtering            | FilterReader,      | FilterInputStream,
                     | FilterWriter       | FilterOutputStream
Converting between   | InputStreamReader, |
Bytes and Characters | OutputStreamWriter |
---------------------+--------------------+-----------------------
Concatenation        |                    | SequenceInputStream
---------------------+--------------------+-----------------------
Object Serialization |                    | ObjectInputStream,
                     |                    | ObjectOutputStream
---------------------+--------------------+-----------------------
Data Conversion      |                    | DataInputStream,
                     |                    | DataOutputStream
---------------------+--------------------+-----------------------
Counting             | LineNumberReader   | LineNumberInputStream
---------------------+--------------------+-----------------------
Peeking Ahead        | PushbackReader     | PushbackInputStream
---------------------+--------------------+-----------------------
Printing             | PrintWriter        | PrintStream
---------------------+--------------------+-----------------------

17.7.  Data Sink Streams

Data sink streams read from or write to specialized data sinks such as strings, files, or pipes. Typically, for each reader or input stream intended to read from a specific kind of input source, java/io contains a parallel writer or output stream that can create it. The following table gives java/io's data sink streams.

Sink Type   Character Streams   Byte Streams
Memory      CharArrayReader,    ByteArrayInputStream,
            CharArrayWriter     ByteArrayOutputStream
            StringReader,       StringBufferInputStream
            StringWriter        StringBufferInputStream
Pipe        PipedReader,        PipedInputStream,
            PipedWriter         PipedOutputStream
File        FileReader,         FileInputStream,
            FileWriter          FileOutputStream
CharArrayReader and CharArrayWriter
ByteArrayInputStream and ByteArrayOutputStream

Use these streams to read from and write to memory. You create these streams on an existing array and then use the read and write methods to read from or write to the array.

FileReader and FileWriter
FileInputStream and FileOutputStream

Collectively called file streams, these streams are used to read from or write to a file on the native file system.

PipedReader and PipedWriter
PipedInputStream and PipedOutputStream

Implement the input and output components of a pipe. Pipes are used to channel the output from one program (or thread) into the input of another.

StringReader and StringWriter
StringBufferInputStream

Use StringReader to read characters from a String as it lives in memory. Use StringWriter to write to a String. StringWriter collects the characters written to it in a StringBuffer, which can then be converted to a String. StringBufferInputStream is similar to StringReader, except that it reads bytes from a StringBuffer.

17.8.  StreamTokenizer

The class StreamTokenizer provides some simple support for parsing bytes or characters from an input stream into tokens such as identifiers, numbers, and strings, optionally ignoring comments and optionally recognizing or ignoring line terminators.

java/io

The hierarchy of classes defined in package http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/package-summary.html

17.9.  A Copy Program

Src/9_was/InOut_1.java.minusSTART_STOP


import java.io.*;

public class InOut_1 {
  public static void main( String args[] ) {
    DataInputStream in;
    DataOutputStream out;
    byte[]  buffer = new byte[1024];
    int     n;

    if ( args.length < 2 )      {
        System.err.println(
             "Usage: java InOut_1 from to");
        System.exit(1);
    }

    try { 
        in = new DataInputStream(
                                new FileInputStream(args[0]) );
        out = new DataOutputStream(
                                new FileOutputStream(args[1]) );
        
        while ( (n = in.read(buffer) ) != -1 ) {
                out.write(buffer, 0, n);
        }

        out.close();
        in.close();

    }
    catch ( FileNotFoundException ef)   {
        System.out.println("File not found: " + args[1]);
    }
    catch ( IOException ef)     {
        System.out.println("File not found: " + args[1]);
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
    }

  }
}

Source Code: Src/9_was/InOut_1.java

Result:

% java InOut_1
% java InOut_1 InOut_2.class x
% diff InOut_1.class x
%

17.10.  Size Matters: The second Copy Program

Does the size of the read and write blocks matter?

Src/9_was/InOut_2.java.minusSTART_STOP


import java.io.*;


public class InOut_2 {
  static final int BUFSIZE = 1024;

  public static void copy( String inF , String outF, int bufSize ) {
    DataInputStream in;
    DataOutputStream out;
    byte[]  buffer = new byte[bufSize];
    int     n;

    
    try { 
        in = new DataInputStream(
                                new FileInputStream(inF) );
        out = new DataOutputStream(
                                new FileOutputStream(outF) );
        
        while ( (n = in.read(buffer) ) != -1 ) {
                out.write(buffer, 0, n);
        }

        out.close();
        in.close();

    }
    catch ( FileNotFoundException ef)   {
        System.out.println(ef.getMessage() );
    }
    catch ( IOException ef)     {
        System.out.println(ef.getMessage() );
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
    }
  }


  public static void main( String args[] ) {
    int     bufSize = BUFSIZE;

    if ( args.length < 2 )      {
        System.err.println(
             "Usage: java InOut_1 from to [size]");
        System.exit(1);
    }

    if ( args.length  == 3 )    {
        try {
                bufSize = Integer.parseInt(args[2]);
        }
        catch ( NumberFormatException e )       {
                System.out.println("Can't convert " + args[2] 
                        + " to an integer.");
        }

    }
    System.out.println("BufferSize = " + bufSize);
    copy(args[0], args[1], bufSize);
  }
}

Source Code: Src/9_was/InOut_2.java

Result:

% for i in 1 2 512 1024 10240
> do
> /usr/bin/time java InOut_2 from to $i && diff from to
> done
BufferSize = 1

real       49.8
user       21.3
sys        24.4
BufferSize = 2

real       27.0
user       10.8
sys        12.3
BufferSize = 512

real        0.8
user        0.2
sys         0.2
BufferSize = 1024

real        0.8
user        0.1
sys         0.2
BufferSize = 10240

real        1.0
user        0.2
sys         0.1

17.11.  Reading from Stdin

Src/14/stdin.java.minusSTART_STOP


import java.io.*;

public class stdin {
  public static void main( String args[] ) {
    LineNumberInputStream input;

    if ( args.length > 1 )      {
        System.err.println(
             "Usage: java stdin file-name");
        System.exit(1);
    }

    try {
        String line;
//
        if ( args.length == 1 ) 
                input = new LineNumberInputStream(
                           new DataInputStream(
                             new FileInputStream(args[0]) ) );
        else
                input = new LineNumberInputStream( System.in );


        while ( ( input.read() )  != -1  ) {
                ;
        }
        System.out.println("# lines = " + input.getLineNumber() );
        input.close();
    }
    catch ( FileNotFoundException e)    {
        System.out.println(e.getMessage());
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
    }
  }
}

Source Code: Src/14/stdin.java

17.12.  Reading/Writing Compressed Files

Src/14/Compressed.java.minusSTART_STOP



/**
  * Opens the file with the data.
  * A rewind will happen, if this method gets called more than once.
  **/
    public void openFileForReading() {
        try {
                if ( isBinaryInput )    {
                        bInputStream = new DataInputStream(
                                                    new GZIPInputStream(
                                                      new FileInputStream(inputFileName)
                                                    )
                                                  );

                } else {
                        inputStream = new BufferedReader(new FileReader(inputFileName));
                }
                ...
        } catch ( Exception e ) {
                e.printStackTrace();
                InOutErr.out.println("ParticleViewExtractor: -openFileForReading- " + e);
        }
    }


   /*
    * Convert Data to Binary format
    */
    public void doConvertToBinary(String fileName)      {
        try {
                BufferedReader inputStream = new BufferedReader(new FileReader(fileName));
                DataOutputStream outputStream = new DataOutputStream(
                                                    new GZIPOutputStream(
                                                      new FileOutputStream(fileName +  ".binary.Z")
                                                    )
    ...                                              );
    }

Source Code: Src/14/Compressed.java

17.13.  A Grep Program

Extract from:
http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/BufferedReader.html

BufferedReader(Reader) 
    Create a buffering character-input
    stream that uses a default-sized input buffer. 
BufferedReader(Reader, int) 
    Create a buffering character-input
    stream that uses an input buffer of the specified
    size. 

Src/9_was/Grep.java.minusSTART_STOP


import java.io.*;

public class Grep {
  public static void main( String args[] ) {
    BufferedReader input;
    PrintWriter    output;

    if ( args.length < 2 )      {
        System.err.println(
             "Usage: java Grep search-string file-name [outputfilename]");
        System.exit(1);
    }

    try {
        String line;
        input = new BufferedReader(
                          new FileReader(args[1])
                                  );
        if ( args.length == 3 )         {
            output = new PrintWriter( new FileWriter(args[2]) );
        } else
            output = new PrintWriter(System.out);





        while ( ( line = input.readLine() )  != null ) {
                if ( line.indexOf(args[0]) >= 0 )
                        output.println(line);
        }
        output.close();
        input.close();
    }
    catch ( FileNotFoundException e)    {
        System.out.println(e.getMessage());
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
    }

  }
}

Source Code: Src/9_was/Grep.java

% java Grep Grep Grep.java
public class Grep {
             "Usage: java Grep search-string file-name [outputfilename]");
% java Grep Grep 
Usage: java Grep search-string file-name [outputfilename]

If you are interessted in line numbers, choose LineNumberReader

Src/9_was/Grep2.java.minusSTART_STOP


import java.io.*;

public class Grep2 {
  public static void main( String args[] ) {
    LineNumberReader input;
    PrintWriter    output;

    if ( args.length < 2 )      {
        System.err.println(
             "Usage: java Grep search-string file-name [outputfilename]");
        System.exit(1);
    }

    try {
        String line;
        input = new LineNumberReader (
                      new  BufferedReader(
                             new FileReader(args[1])
                                         )
                                     );
        if ( args.length == 3 )         {
            output = new PrintWriter( new FileWriter(args[2]) );
        } else
            output = new PrintWriter(System.out);

        while ( ( line = input.readLine() )  != null ) {
                if ( line.indexOf(args[0]) >= 0 )
                        output.println(input.getLineNumber() + 
                                ": " + line);
        }
        output.close();
        input.close();
    }
    catch ( FileNotFoundException e)    {
        System.out.println(e.getMessage());
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
    }

  }
}

Source Code: Src/9_was/Grep2.java

% java Grep2 Grep Grep.java
3: public class Grep {
10:          "Usage: java Grep search-string file-name [outputfilename]");
% 

17.14.  Regualar Expressions

17.15.  Regualar Expressions in Java

See also here: Pattern

17.16.  Example 1

Src/9_reg_ex/EmailValidation.java.minusSTART_STOP


/*
 * Checks for invalid characters
 * in email addresses
 */

import java.util.regex.*;

public class EmailValidation {

  /*
   * Checks for email addresses starting with
   * inappropriate symbols like dots or @ signs.
   */
   public static void checkForPorA(String aPossibleEmail )      {
      Pattern p = Pattern.compile("^\\.|^\\@");
      Matcher m = p.matcher(aPossibleEmail);
      if (m.find())
         System.err.println(aPossibleEmail + " - Email addresses don't start" +
                            " with dots or @ signs.");
      else
         System.err.println(aPossibleEmail + " is valid.");
   }

  /*
   * Checks for email addresses starting with
   * www.
   */
   public static void checkForWWW(String aPossibleEmail )       {
      Pattern p = Pattern.compile("^www\\.");
      Matcher m = p.matcher(aPossibleEmail);
      if (m.find())
         System.err.println(aPossibleEmail + " - Email addresses don't start" +
                            " with www.");
      else
         System.err.println(aPossibleEmail + " is valid.");
   }


  /*
   * Checks for invalid characters in email addresses.
   */
   public static void checkForInvalidC(String aPossibleEmail )  {
      Pattern p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
      Matcher m = p.matcher(aPossibleEmail);
      StringBuffer sb = new StringBuffer();
      boolean result = m.find();
      boolean deletedIllegalChars = false;

      while(result) {
         deletedIllegalChars = true;
         m.appendReplacement(sb, "");
         result = m.find();
      }

      if (deletedIllegalChars) {
         System.out.println("It contained incorrect characters" +
                           " , such as spaces or commas.");
      }
   }


   public static void main(String[] args) throws Exception {
                                 

      checkForPorA("hpb@cs.rit.edu");
      checkForPorA("@cs.rit.edu");

      checkForWWW("www.cs.rit.edu");

      checkForInvalidC("hpb@cs.rit.edu");
      checkForInvalidC("p b@cs.rit.edu");

   }
}

Source Code: Src/9_reg_ex/EmailValidation.java

17.17.  Example 2

Src/9_reg_ex/TheN.java.minusSTART_STOP


/*
 * Checks for invalid characters
 * in email addresses
 */

import java.util.regex.*;

public class TheN {

  /*
   * Palindroms
   */
   public static void checkForP(String aPossibleEmail ) {
      Pattern p = Pattern.compile("^.$");
      Matcher m = p.matcher(aPossibleEmail);
      if (m.find())
         System.err.println(aPossibleEmail + " one character");
      else
         System.err.println(aPossibleEmail + " more than one character");
   }

   public static void checkForP2(String aPossibleEmail )        {
      Pattern p = Pattern.compile("^(.).\\1$");
      Matcher m = p.matcher(aPossibleEmail);
      if (m.find())
         System.err.println(aPossibleEmail + " 2 char palindrom");
      else
         System.err.println(aPossibleEmail + " ! a 2 char palindrom");
   }

   public static void main(String[] args) throws Exception {
                                 

      checkForP("a");
      checkForP("aa");

      checkForP2("a");
      checkForP2("ata");

      if (  Pattern.matches("^(.)\\1$", "aa" ))
                System.err.println("palindrom");

   }
}

Source Code: Src/9_reg_ex/TheN.java

17.18.  Serializing Objects

Object writer:

Src/9_was/ObjectWriter_1.java.minusSTART_STOP


import java.io.*;
import java.util.Date;

public class ObjectWriter_1 {
  public static void main( String args[] ) {

    Date d = new Date();

    try {
        FileOutputStream ostream =
                      new FileOutputStream("object_1.data");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeInt(12345);
          System.out.println("Integer = " + 1234);
        p.writeObject("Today");
          System.out.println("String = " + "Today");
        p.writeObject(d);
          System.out.println("Date = " + d);
        p.flush();
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
 
  }
}

Source Code: Src/9_was/ObjectWriter_1.java

% java ObjectWriter_1
Integer = 1234
String = Today
Date = Tue Oct 15 15:28:59 EDT 2002

Object Reader:

Src/9_was/ObjectReader_1.java.minusSTART_STOP


import java.io.*;
import java.util.Date;

public class ObjectReader_1 {
  public static void main( String args[] ) {

    try {
        FileInputStream istream =
                      new FileInputStream("object_1.data");
        ObjectInputStream p = new ObjectInputStream(istream);
        int i = p.readInt();
          System.out.println("Integer = " + i);
        String today = (String)p.readObject();
          System.out.println("String = " + today);
        Date date = (Date)p.readObject();
          System.out.println("Date = " + date);
        p.close();
        istream.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( ClassNotFoundException e)   {
        System.out.println(e.getMessage());
    }
 
  }
}

Source Code: Src/9_was/ObjectReader_1.java

% java ObjectReader_1
Integer = 1234
String = Today
Date = Tue Oct 15 15:29:07 EDT 2002

ls -l o*a
-rw-------   1 hpb      fac           60 Oct  4 10:49 object_1.data
yps 9 85 od -c object_1.data
0000000 254 355  \0 005   w 004  \0  \0   0   9   t  \0 005   T   o   d
0000020   a   y   s   r  \0 016   j   a   v   a   .   u   t   i   l   .
0000040   D   a   t   e   h   j 201 001   K   Y   t 031 003  \0  \0   x
0000060   p   w  \b  \0  \0  \0 326 365   <   o 232   x
0000074

When an object is serialized, any object reference it contains are also serialized. A HashTable example.

Src/9_was/ObjectWriter_2.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class ObjectWriter_2 {
  public static void main( String args[] ) {

    Hashtable aHashTable = new Hashtable();
    aHashTable.put("plus  Movie", "A little Voice");
    aHashTable.put("minus Movie", "Independence Day");

    try {
        FileOutputStream ostream =
                      new FileOutputStream("object_2.data");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeObject(aHashTable);
          System.out.println("aHashTable = " + aHashTable.toString());
        p.flush();
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
 
  }
}

Source Code: Src/9_was/ObjectWriter_2.java

% java ObjectWriter_2
aHashTable = {minus Movie=Independence Day, plus  Movie=A little Voice}

Src/9_was/ObjectReader_2.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class ObjectReader_2 {
  public static void main( String args[] ) {

    Hashtable aHashTable;

    try {
        FileInputStream istream =
                      new FileInputStream("object_2.data");
        ObjectInputStream p = new ObjectInputStream(istream);

        aHashTable= (Hashtable)p.readObject();
          System.out.println("aHashTable = " + aHashTable.toString());
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( ClassNotFoundException e)   {
        System.out.println(e.getMessage());
    }
  }
}

Source Code: Src/9_was/ObjectReader_2.java

% java ObjectReader_2
aHashTable = {minus Movie=Independence Day, plus  Movie=A little Voice}

17.19.  Can an Object include itself?

Src/9_was/Self.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class Self {
  public static void main( String args[] ) {

    Hashtable aHashTable = new Hashtable();
    aHashTable.put("plus  Movie", "A little Voice");
    aHashTable.put("The HashTable", aHashTable);

    try {
        FileOutputStream ostream =
                      new FileOutputStream("self.data");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeObject(aHashTable);
        p.flush();
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println(e.getMessage());
        e.printStackTrace();
        System.exit(1);
    }
 
  }
}

Source Code: Src/9_was/Self.java

% java Self
% od -c self.data
0000000 254 355  \0 005   s   r  \0 023   j   a   v   a   .   u   t   i
0000020   l   .   H   a   s   h   t   a   b   l   e 023 273 017   %   !
0000040   J 344 270 003  \0 002   F  \0  \n   l   o   a   d   F   a   c
 ...
0000160       M   o   v   i   e   t  \0 016   A       l   i   t   t   l
0000200   e       V   o   i   c   e   x
0000210

Src/9_was/Self_Reader.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class Self_Reader {
  public static void main( String args[] ) {

    Hashtable aHashTable;

    try {
        FileInputStream istream =
                      new FileInputStream("self.data");
        ObjectInputStream p = new ObjectInputStream(istream);

        aHashTable= (Hashtable)p.readObject();
        System.out.println("plus  Movie = " + aHashTable.get("plus  Movie"));
        System.out.println("The HashTable" + aHashTable.get("The HashTable"));
        System.out.println("aHashTable = " + aHashTable.toString());
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( ClassNotFoundException e)   {
        System.out.println(e.getMessage());
    }
  }
}

Source Code: Src/9_was/Self_Reader.java

% java Self_Reader 2>&1 | more // version jdk1.3.1
plus  Movie = A little Voice
java/lang/StackOverflowError
        at java/lang/StringBuffer.<init>(StringBuffer.java)
        at java/gutil.Hashtable.toString(Hashtable.java)
        at java/gutil.Hashtable.toString(Hashtable.java)
 ...
% java Self_Reader // version jdk1.4
plus  Movie = A little Voice
The HashTable{The HashTable=(this Map), plus  Movie=A little Voice}
aHashTable = {The HashTable=(this Map), plus  Movie=A little Voice}

17.20.  Make it Serializable

The first shot is using a 'Serializable' class:

Src/9_was/ObjectWriter_3.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class ObjectWriter_3 extends Hashtable {
  int local = 42;

  public static void main( String args[] ) {

    ObjectWriter_3 aObjectWriter_3 = new ObjectWriter_3();

    try {
        FileOutputStream ostream =
                      new FileOutputStream("object_3.data");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeObject(aObjectWriter_3);
          System.out.println("aObjectWriter_3 = " + aObjectWriter_3.toString());
          System.out.println("aObjectWriter_3.local = " + aObjectWriter_3.local);
        p.flush();
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
 
  }
}

Source Code: Src/9_was/ObjectWriter_3.java

% java ObjectWriter_3
aObjectWriter_3 = {}
aObjectWriter_3.local = 42

Src/9_was/ObjectReader_3.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class ObjectReader_3 {
  public static void main( String args[] ) {

    ObjectWriter_3 aObjectWriter_3;

    try {
        FileInputStream istream =
                      new FileInputStream("object_3.data");
        ObjectInputStream p = new ObjectInputStream(istream);

        aObjectWriter_3= (ObjectWriter_3)p.readObject();
          System.out.println("ObjectWriter_3.local = " + aObjectWriter_3.local);
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    catch ( ClassNotFoundException e)   {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
  }
}

Source Code: Src/9_was/ObjectReader_3.java

% java ObjectReader
aObjectWriter_3.local = 42

--
Class of the object
--
Class signature
--
Values of all non-transient and non-static members, including members that refer to other objects

Src/9_was/ObjectWriter_4.java.minusSTART_STOP


import java.io.*;
import java.util.*;

public class ObjectWriter_4 implements Serializable {
  int local = 42;
  private void writeObject(ObjectOutputStream s) throws IOException {
           s.defaultWriteObject();
         // customized serialization code
  }

  private void readObject(ObjectInputStream s) throws IOException  {
        try {
                s.defaultReadObject();
        }
        catch ( ClassNotFoundException e)       {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

         // customized deserialization code
         //  ...
         // followed by code to update the object, if necessary
  }

  public static void main( String args[] ) {

    ObjectWriter_4 aObjectWriter_4 = new ObjectWriter_4();

    try {
        FileOutputStream ostream =
                      new FileOutputStream("object_4.data");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeObject(aObjectWriter_4);
          System.out.println("aObjectWriter_4 = " + aObjectWriter_4.toString());
          System.out.println("aObjectWriter_4.local = " + aObjectWriter_4.local);
        p.flush();
        p.close();
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
 
  }
}

Source Code: Src/9_was/ObjectWriter_4.java

% java ObjectWriter_4
aObjectWriter_4 = ObjectWriter_4@1dc60810
aObjectWriter_4.local = 42

The reader program must not be modified.

17.21.  StreamTokenizer

The StreamTokenizer class takes an input stream and parses it into "tokens", allowing the tokens to be read one at a time. The parsing process is controlled by a table and a number of flags that can be set to various states. The stream tokenizer can recognize identifiers, numbers, quoted strings, and various comment styles.

Each byte read from the input stream is regarded as a character in the range '\u0000' through '\u00FF'. The character value is used to look up five possible attributes of the character: white space, alphabetic, numeric, string quote, and comment character. Each character can have zero or more of these attributes.

In addition, an instance has four flags. These flags indicate:

A typical application first constructs an instance of this class, sets up the syntax tables, and then repeatedly loops calling the nextToken method in each iteration of the loop until it returns the value TT_EOF.

The first program:

Src/9_was/St_1.java.minusSTART_STOP


import java.io.*;
public class St_1 {
  public static void main( String args[] ) {
    StreamTokenizer input;
    if ( args.length > 1 )      {
        System.err.println("Usage: java St [file-name]");
        System.exit(1);
    }
    try {
        String line;
        if ( args.length == 1 )
            input = new StreamTokenizer( new FileReader(args[0]) );
        else
            input = new StreamTokenizer(
                        new InputStreamReader(System.in) );
        while ( input.TT_EOF != input.nextToken() ) {
                System.out.println(input.lineno() + ": "
                        + input.toString());
        }
    }
    catch ( FileNotFoundException e)    {
        System.out.println(e.getMessage());
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println("Exception occurred: " + e.getMessage() );
        e.printStackTrace();
    }
  }
}

Source Code: Src/9_was/St_1.java

Result:

% head -1 /etc/passwd 
root:x:0:1:Super-User:/:/sbin/sh
% head -1 /etc/passwd  | java St_1
1: Token[root], line 1
1: Token[':'], line 1
1: Token[x], line 1
1: Token[':'], line 1
1: Token[n=0.0], line 1
1: Token[':'], line 1
1: Token[n=1.0], line 1
1: Token[':'], line 1
1: Token[Super-User], line 1
1: Token[':'], line 1

% java St_1 /etc/passwd | sed 7q
1: Token[root], line 1
1: Token[':'], line 1
1: Token[x], line 1
1: Token[':'], line 1
1: Token[n=0.0], line 1
1: Token[':'], line 1
1: Token[n=1.0], line 1

% java St_1 
hello
1: Token[hello], line 1
a b:c d;e
2: Token[a], line 2
2: Token[b], line 2
2: Token[':'], line 2
2: Token[c], line 2
2: Token[d], line 2
2: Token[';'], line 2
2: Token[e], line 2

% java St_1 
aa ///
1: Token[aa], line 1
sss // wwww
2: Token[sss], line 2
222 + # 
3: Token[n=222.0], line 3
3: Token['+'], line 3
3: Token['#'], line 3

The second program is a begining of a calculator:

Src/9_was/St_2.java.minusSTART_STOP


import java.io.*;

public class St_2 {

  StreamTokenizer input;

  public void adjustT() {
        input.resetSyntax();
        input.commentChar('#');          // comments from #
                                         // to end-of-line
        input.wordChars('0', '9');       // parse decimal
                                         // numbers as words
        input.wordChars('.', '.');
        input.wordChars('+', '+');       // operators as words
        input.wordChars('-', '-');       // operators as words
        input.wordChars('*', '*');       // operators as words
        input.wordChars('/', '/');       // operators as words
        input.whitespaceChars(0, ' ');   // ignore white space
        input.eolIsSignificant(true);    // need '\n'
  }

  public void processInput() throws IOException {
        while ( input.TT_EOF != input.nextToken() ) {
                if ( input.ttype != input.TT_EOL )
                        System.out.println(input.lineno() + ": " +
                                                input.sval);
                        else
                                System.out.println("Saw EOL");
        }
 }


  public static void main( String args[] ) {

    St_2 aSt_2 = new St_2();

    if ( args.length > 1 )      {
        System.err.println(
             "Usage: java St [file-name]");
        System.exit(1);
    }

    try {
        String line;
        if ( args.length == 1 )
            aSt_2.input = new StreamTokenizer(
                              new FileReader(args[0]) );
        else
            aSt_2.input = new StreamTokenizer(
                               new InputStreamReader(System.in) );
        aSt_2.adjustT();
        aSt_2.processInput();

    }
    catch ( FileNotFoundException e)    {
        System.out.println(e.getMessage());
    }
    catch ( IOException e)      {
        System.out.println(e.getMessage());
    }
    catch ( Exception e)        {
        System.out.println("ExceptionType occurred: " + 
                e.getMessage() );
        e.printStackTrace();
    }
  }
}

Source Code: Src/9_was/St_2.java

Result:

% java St_2 
Saw EOL
2 + 3
1: 2
1: +
1: 3
Saw EOL
2 - 3
2: 2
2: -
2: 3
Saw EOL

A simple calculator:

The first idea for the process loop:

  public void processInput() throws IOException {
        while ( input.TT_EOF != new Expression(input) ) {
                ;
        }
 }

What do you think?

Result:

% java Expression
2 * ( 1 - 2 )
-2.0
Ep

17.22.  Not Discussed.

A piped input stream should be connected to a piped output stream; the piped input stream then provides whatever data bytes are written to the piped output stream. Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread. Attempting to use both objects from a single thread is not recommended, as it may deadlock the thread. The piped input stream contains a buffer, decoupling read operations from write operations, within limits

A PushbackInputStream adds functionality to another input stream, namely the ability to "push back" or "unread" one byte. This is useful in situations where it is convenient for a fragment of code to read an indefinite number of data bytes that are delimited by a particular byte value; after reading the terminating byte, the code fragment can "unread" it, so that the next read operation on the input stream will reread the byte that was pushed back. For example, bytes representing the characters constituting an identifier might be terminated by a byte representing an operator character; a method whose job is to read just an identifier can read until it sees the operator and then push the operator back to be re-read.

A transparent stream that updates the associated message digest using the bits going through the stream. To complete the message digest computation, call one of the digest methods on the associated message digest after your calls to one of this digest input stream's read methods.

This class implements an input stream filter for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries.

Weiter | Weiter | Weiter | Weiter | Kommentar


Created by unroff, java2html & & hp-tools. © by csfac. All Rights Reserved (2010).
It is not allowed to print these pages on a CAST printer.
Last modified 01/April/10