Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

Search: 

  Tutorial: Reading textual data: Fun with streams - JavaWorld - April 1999

Reading textual data: Fun with streams - JavaWorld - April 1999

Tutorial Details:

Reading textual data: Fun with streams
Reading textual data: Fun with streams
By: By Merlin Hughes
Find out how to extend and customize the character-stream classes to easily read textual data
ever let it be said that I'm happy to rush out a simple article (or book) just to meet a publisher's deadline. What started out as a basic, inefficient character-stream filter, designed to read a stream of digits and parse it into a number, has gradually ballooned into a small stream library sporting unnecessary features and go-faster stripes. Not only has the evolving character-stream library discarded many genetically-inferior siblings along the way, it's behind schedule! (This brings back memories of that 300-page manuscript I discarded in favor of starting anew. I think I'm beginning to see a destructive pattern emerging...)
I initially set out to design a data-reading character-stream filter class. Analogous to the byte-stream filter DataInputStream , this character-stream filter was intended to provide the capability to read textual data from a character stream (namely the output of a human or the PrintWriter println() method).
Let me now, in retrospect, describe what I actually implemented.
First, I created an UndoReader class. This character-stream filter supports three special methods:
checkpoint()
commit()
rollback()
As you read characters through the stream, you have the option to checkpoint the stream -- that is, save the stream's current state and put it into a mode such that it stores all data subsequently read through it. From that point on, the UndoReader stores all the data you read. After any amount of reading, choosing to commit the stream will cause the stored data to be discarded, after which reading proceeds undisturbed. Alternatively, choosing to rollback the stream will cause it to rewind and revert to reading from the position at which you asserted the checkpoint -- just as if you hadn't yet read anything. This stream also supports a couple of related methods.
Next, I implemented the DataReader class, the character-stream filter. This class makes use of the UndoReader class and provides methods to read all the primitive Java types ( readInt() , readFloat() , readBoolean() , and so on). What is special about this class is that if you attempt to read a primitive from the stream and it turns out the stream data is incorrect -- if, for example, you attempt to read a Boolean and the next token in the stream is truthfulness -- it rolls back, un-reading any characters read during the erroneous operation, and throws an exception. The stream also supports a feature whereby it can read data one line at a time, signaling each time the end of a line is reached (among other wonders).
The classes I developed will only work in JDK 1.1-plus. Adapting them to work as InputStream s, usable under JDK 1.0.2, should be quite easy, however.
Justification for UndoReader
In the interest of brevity, I'll spare you an introduction to character streams . Todd Sundsted's November 1997 How-To Java column should serve that purpose quite adequately; if you want an introduction to byte streams , check out Todd's October 1997 column. For further details of the Java stream classes, I refer you to Java Network Programming, Second Edition, which I coauthored with Michael Shoffner and Derek Hamner, and which is due out any day now. (See Resources .)
What I should perhaps explain is my justification for the UndoReader class. At the most abstract level, I want the ability to undo a series of read operations, because otherwise my DataReader class will violate the basic law of propriety: It would be improper for an erroneous attempt at reading an int to end up consuming a Boolean . Furthermore, the behavior of my class wouldn't necessarily be clearly defined in the presence of such an error: the amount of erroneous input consumed would be implementation-dependent, and exposing implementation-dependent details of this nature simply invites abuse.
Those readers familiar with the stream classes may then ask about the mark() and reset() methods, or indeed the PushbackReader class: Do these basic features of the stream API not already address my needs? Indeed, use of the mark() and reset() methods does allow a sequence of read operations to be undone, and the PushbackReader unread() methods can be used to the same effect. However, both of these options are bounded. Therefore you must, in each case, declare ahead of time the maximum volume of data you will un-read. In our situation, no such limit exists for textual data: "00...01" is a valid integer, just as "00...0z" is not. I cannot, simply to avoid writing an extra class, presume to impose arbitrary limitations on the data I will process.
Thus rationalized, we can now proceed with the code.
Class UndoReader
The UndoReader class is a character-stream filter that provides unbounded checkpoint, commit, and rollback operations and an additional undo facility.
Figure 1. Using methods checkpoint(), commit(), rollback(), and undo()
When checkpoint() is used, it proceeds to store all data read through it in an internal, expanding buffer
When commit() is used, the stored contents of the checkpoint buffer are discarded and further reads are no longer stored
When rollback() is used, reading reverts to data stored in the internal buffer; when this is used up, reading proceeds as normal
Any number of reads performed since a checkpoint can be undone without a full rollback by partially reverting in the internal buffer
It is an error to checkpoint a stream that has already been checkpointed or to commit, rollback, or undo a noncheckpointed stream
We must support the case where a checkpoint is placed while we're still reading out of the internal buffer
The class definition
We'll start by looking at our class definition:
package org.merlin.io;
import java.io.*;
public class UndoReader extends Reader {
protected static final int INITIAL_UNDO_SIZE = 64;
protected Reader reader;
protected int[] buffer;
protected int index, stored, capacity;
protected boolean storing, restoring, closed;
public UndoReader (Reader reader) {
this (reader, INITIAL_UNDO_SIZE);
}
public UndoReader (Reader reader, int capacity) {
super (reader);
this.reader = reader;
this.capacity = capacity;
buffer = new int[capacity];
}
...
}
Ordinarily, a character-stream filter would inherit from FilterReader ; however in this case we must override the entire function of the Reader superclass so FilterReader will be of no benefit.
The constructors we provide allow the attached stream, and optionally the initial buffer capacity, to be specified. As the internal buffer can grow as necessary, this will only affect efficiency. In the constructor, we initialize the buffer variable, in which checkpoint data are stored, and the capacity variable, which defines the current size of our buffer.
You may notice that the checkpoint buffer is, in fact, an int array and not a char array. The reason: I wish to be able to store not only normal character data, but the end of file (EOF) [-1] in this buffer. Although there may be other ways to implement this, my purpose is served by this solution.
Other variables related to this buffer are stored , for the amount of checkpoint data that have been stored; and index , for the current read index when data are read from the buffer. The storing flag indicates that a stream has been checkpointed, so data should be stored in the checkpoint buffer; restoring indicates a rollback, so data should be read from the checkpoint buffer; and closed indicates the stream has been closed.
Figure 2. Internals of the UndoReader class
The read() methods
We now look at the operation of reading a single character:
public int read () throws IOException {
synchronized (lock) {
int result;
if (!storing && !restoring) {
result = reader.read ();
} else if (restoring) {
result = buffer[index ++];
if (index >= stored)
restoring = false;
} else {
result = reader.read ();
if (stored + 1 > capacity)
ensureCapacity (1);
buffer[stored ++] = result;
}
return result;
}
}
protected void ensureCapacity (int amount) {
capacity = capacity * 2 + amount;
int[] copy = new int[capacity];
System.arraycopy (buffer, 0, copy, 0, index);
buffer = copy;
}
We start by synchronizing on lock . This variable, inherited from the superclass, is the attached stream ( reader ) we passed to the superconstructor. It is more efficient for us to synchronize on reader than on this , because if we subsequently call synchronized methods on the attached stream, those synchronization calls will not incur any significant costs.
Figure 3. Synchronization efficiency
If we have neither placed the stream in the checkpoint buffer nor rolled it back, we can simply read a character from the attached stream. Otherwise, if we have rolled it back, we must return a character from the internal checkpoint buffer. If we then reach the end of the internal buffer, we can reset restoring . Otherwise, the stream has been checkpointed, so we must read a character from the attached stream and store it in the checkpoint buffer.
Before inserting data into the checkpoint buffer, we use the ensureCapacity() method to enlarge the array to hold the extra datum. Whenever we perform this enlargement, we more than double the buffer's size. This means it will grow very rapidly to accommodate our needs. (It could, for instance, grow from 1 byte to 1 megabyte in just 20 expansions.)
Read multiple characters in one call:
public int read (char[] dst, int offset, int length) throws IOException {
synchronized (lock) {
int result;
if (!storing && !restoring) {
result = reader.read (dst, offset, length);
} else if (restoring) {
if (buffer[index] < 0) {
result = buffer[index ++];
} else {
result = (length < stored - index) ? length : stored - index;
for (int i = 0; i < result; ++ i)
dst[offset + i] = (char) buffer[index ++];
}


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Reading textual data: Fun with streams - JavaWorld - April 1999

View Tutorial:
Reading textual data: Fun with streams - JavaWorld - April 1999

Related Tutorials:

Displaying 1 - 50 of about 253 Related Tutorials.

Java Interview Questions - Page 11
; Answer: The ObjectInputStream class supports the reading of objects from input streams. Question:  How are this() and super() used
 
Writing and reading from/to a serialized file through Hash Table in Java
Writing and reading from/to a serialized file through Hash Table in Java Writing and reading from/to a serialized file through Hash...("Closing all output streams...\n");    
 
Reading Request Information
Reading Request Information Reading Request Information                         
 
Java error reading from file
java error reading from file Java error reading...;    Java error reading file... In this Tutorial we help you in understanding a n example from Java error reading
 
Reading Request Information

 
Use of PreferenceStore class
values to the files or streams and to load the default values from the file or streams. The method setDefault(String name, String value) sets the default value
 
Java I/0 Examples
. Java InputStream is defined for reading the stream, byte stream and array of byte stream. Classes and Interfaces of the I/O Streams... in the given table.     Reading Text from
 
Reading And Writing Excel File
How we can pass various data types into cell in an excel sheet using jsp reading and writing excel file... that it is used to read the excel file. After reading the excel file we use write() method
 
Reading RDF file in Java
Reading RDF file in Java Reading RDF file in Java                       
 
Reading File into ByteArray
Reading File into ByteArray Reading File into ByteArray                        
 
Reading XML from a File
XML,XML Tutorials,Online XML Tutorial,XML Help Tutorials Reading XML from a File        ... for reading XML from a  file are described below :- File f = new File("
 
Reading a File into a Byte Array
Java Read File into Byte Array,Read File into Byte Array Java,Array Program in Java Reading a File into a Byte Array             
 
Reading an XML document using JDOM
Reading an XML document using JDOM, XML,XML Tutorials,Online XML Tutorial,XML Help Tutorials Reading an XML document using JDOM... used in code given below for reading an XML document using JDOM:- SAXBuilder
 
Reading XML Data from a Stream
Reading XML Data from a Stream, XML,XML Tutorials,Online XML Tutorial,XML Help Tutorials Reading XML Data from a Stream... are some of the methods used in code given below for Reading XML Data
 
Reading Lines from a String Using a Regular Expression
Reading Lines from a String Using a Regular Expression Reading Lines from a String Using a Regular Expression... given in the section for the best illustration of the procedure of reading
 
Reading ISO Latin-1 Encoded Data in Java
Read Encoded Latin,Reading ISO Latin-1 Encoded Data in Java Reading ISO Latin-1 Encoded Data in Java   ... for reading contents from the specified file in standard ISO-1 format using the "
 
Reading UTF - 8 Encoded Data in Java
Java UTF8,Read UTF 8,Read UTF8 in Java,Reading UTF-8 Encoded Data Reading UTF - 8 Encoded Data in Java  ...; Introduction It supports standard UTF-8 when reading and writing strings through
 
Making Tokens of a Java Source Code
in understanding Java programming in the most simplest way. Here after reading this lesson... ,after reading a file we need to generate a tokens out of that file so, we use
 
Making Tokens of a Java Source Code
. Now we need to read the file so that we can use FileReader class ,After reading
 
Java - Read file Applet
of the reading file from an applet. This program illustrates you how an applet can read
 
Java Read File Line by Line - Java Tutorial
be read by a data input stream. Data input streams and data output streams represent... as to provide for the efficient reading of characters, arrays, and lines. The buffer.... Programs that use DataInputStreams for textual input can be localized by replacing
 
Getting The XML Root Element
;        After reading this section
 
GPS Terminology
; Here are some of the most common words that you will come across while reading
 
JSDAI
; JSDAI? is an Application Programming Interface (API) for reading, writing
 
Java read file line by line - Java Tutorial
DataInputStreams for reading textual input line by line with an appropriate BufferedReader...; Introduction Lets understand some I/O streams that are used to perform reading and writing operation in a file. In the section of Java Tutorial you
 
Read Text from Standard IO
package. It acts as an abstract class for reading character streams... Reading Text from the Standard Input,Java Read from Standard Input - Java I/O Tutorials Reading Text from the Standard
 
Java I/0 Examples
. Java InputStream is defined for reading the stream, byte stream and array of byte stream. Classes and Interfaces of the I/O Streams... in the given table.     Reading Text from
 
How to make a blooming Face.
am sure that you can design as you want by reading this tutorial. Open A Picture
 
Struts 2 Date Examples
available in the Struts 2 Framework. After reading the tutorials you will lean how
 
Struts 2 Date Examples
available in the Struts 2 Framework. After reading the tutorials you will lean how
 
What is Java I/O?
are used for reading from and writing to byte streams, respectively... class is used for reading the data such as a byte and array of bytes... the programming interface for all input streams that are inherited from
 
Definition of Bioinformatics
deciphered! In other words, scientists have succeeded in reading the chain of more
 
Multiple Value initialization and retrieval by put and get method
out the flow of using put and get method of the preferences. After reading
 
Counter in Init() Method
and by reading the init parameter to know from where the counting will begin. In this program
 
Java - Read file Applet
of the reading file from an applet. This program illustrates you how an applet can read
 
Open Source FTP
reading some of the comments for the blog entry, OK is pretty much accurate. I
 
Linux Books
is to explain the use of the GNU C and C++ compilers, gcc and g++. After reading... places (see section Further reading). Experienced programmers who
 
Spoon JDT
, methods, fields, statements, expressions...) can be accessed both for reading
 
Summary: I/O
() Should close when finished reading. BufferedWriter Methods voidbw.writeLine...); } Copyright 1999 Fred Swartz Last update: 2000-02-30
 
Convert Image Formats
streams, serialization and the file system. Classes  ImageReader....ImageIO for reading and writing the images respectively. The class... are reading the image from system by using  read() method of ImageIO
 
Zip File Using Java
(such as image data), for reading streams of characters by considering FileReader
 
Changes in I/O
is newly added in JAVA SE 6. Reading passwords without echoing their text JAVA SE... to the Standard Streams. Its a single, predefined object of Console type that provide most of the same features as by Standard Streams, and others besides. The Console
 
Using a Random Access File in Java
in a sequential but Unlike the input and output streams java.io. RandomAccessFile is used for both reading and writing files A random access file treats with a large array... where the reading or writing operation has to be done. Random AccessFile implements
 
Zip Folder Using Java
to read stream of row bytes such as image data, for reading streams of characters
 
Summary: Methods
Copyright 1999 Fred Swartz
 
Open Source Business Model
not generate stable and scalable revenue streams. In actuality, in the 21st... 1999, eZ systems has been creating Open Source software and serves its customers... source business model On December 1999, Matra Datavision announced the adoption
 
Transforming XML with SAXFilters
is a convenience class for reading character files. it is generally meant for reading streams of characters. CustomFilter filter = new CustomFilter():-creates a custom
 
Console I/O
the debugging phase. Console I/O streams There are three predefined I/O streams..., and output streams. System.in // an InputStream. System.out
 
Python Programming Books
of you make donations each month (out of about a thousand of you reading the text...://diveintopython.org/. If you're reading it somewhere else, you may not have the latest version... changes that have taken place since the release of the first edition in 1999
 
mediniQVT
in the textual concrete syntax of the Relations language Trace management
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.