Java Programming/Streams

The most basic input and output in Java ( and   fields that have been used in the Basic I/O) is done using streams. Streams are objects that represent sources and destinations of data. Streams that are sources of data can be read from, and streams that are destinations of data can be written to. A stream in Java is an ordered sequence of bytes of undetermined length. Streams are ordered and in sequence so that the java virtual machine can understand and work upon the stream. Streams are analogous to water streams. They exist as a communication medium, just like electromagnetic waves in communication. The order or sequence of bytes in a Java stream allow the virtual machine to classify it among other streams.

Java has various inbuilt streams implemented as classes in the package  like the classes of   and. Streams can be classed as both input and output streams. All Java streams are derived from Input Stream and Output Stream  classes. They are abstract base classes meant for other stream classes. The  is the input stream class derivative and analogically   is the output counterpart. Both are basic classes used to directly interact with input and output through console, similarly follows. Also Java has streams to communicate across different parts of a program or even among threads. There are also classes that "filter" streams, changing one format to another (e.g. class, which translates various primitive types to byte streams).

It is a characteristic of streams that they deal only in one discrete unit of data at a time, and different streams deal with different types of data. If one had a stream that represented a destination for bytes, for example, one would send data to the destination one byte at a time. If a stream was a source of byte data, one would read the data a byte at a time. Because this is the only way to access data from a stream, in this latter case, we wouldn't know when we had read all the data from the stream until we actually got there. When reading a stream, one generally has to check each unit of data each read operation to see if the end of the stream has been reached (with byte streams, the special value is the integer -1, or FFFF hex).

Input streams
Input streams acquire bytes for our programmed java application/program (e.g. a file, an array, a keyboard or monitor, etc.). is an abstract class that represents a source of byte data. It has a  method, which returns the next byte in the stream and a   method, which should be called by a program when that program is done with the stream. The  method is overloaded, and can take a byte array to read to. It has a  method that can skip a number of bytes, and an   method that a program can use to determine the number of bytes immediately available to be read, as not all the data is necessarily ready immediately. As an abstract class, it cannot be instantiated, but describes the general behavior of an input stream. A few examples of concrete subclasses would be, which reads from a byte array, and  , which reads byte data from a file.

In the following example, we print "Hello world!" on the screen several times. The number of times the message is printed is stored in a file named. This file should only contain a integer and should be placed in the same folder of the  class.

The  method is not always mandatory but can avoid some inter-process concurrency conflicts. However if it occurs before a  or   (in the same process) they return the warning.

The class start to identify the filename with a  object. The  object is used by an input stream as the source of the stream. We create a buffer and a character to prepare the data loading. The buffer will contain all the file content and the character will temporary contain each character present in the file, one after one. This is done in the loop. Each iteration of the loop will copy a character from the stream to the buffer. The loop ends when no more character is present in the stream. Then we close the stream. The last part of the code use the data we have loaded in from the file. It is transformed into string and then into an integer (so the data must be an integer). If it works, the integer is used to determine the number of time we print "Hello world!" on the screen. No try/catch block has been defined for readability but the thrown exceptions should be caught.

Let's try with the following source file:

We should obtain this:

There is also  which is an abstract class that represents a source of character data. It is analogous to, except that it deals with characters instead of bytes (remember that Java uses Unicode, so that a character is 2 bytes, not one). Its methods are generally similar to those of. Concrete subclasses include classes like, which reads characters from files, and  , which reads characters from strings. You can also convert an  object to a Reader object with the   class, which can be "wrapped around" an   object (by passing it as an argument in its constructor). It uses a character encoding scheme (which can be changed by the programmer) to translate a byte into a 16-bit Unicode character.

Output streams
Output Streams direct streams of bytes outwards to the environment from our program or application. is an abstract class which is the destination counterpart of. has a  method which can be used to write a byte to the stream. The method is overloaded, and can take an array as well. A  method closes the stream when the application is finished with it, and it has a   method. The stream may wait until it has a certain amount before it writes it all at once for efficiency. If the stream object is buffering any data before writing it, the  method will force it to write all of this data. Like, this class cannot be instantiated, but has concrete subclasses that parallel those of  , eg  ,  , etc.

In the following example, we store the current time in an already existing file called  located in the same folder than the class.

This case is more simple as we can put all the data in the stream at the same time. The first part of the code generate a string containing the current time. Then we create a  object identifying the output file and an output stream for this file. We write the data in the stream, flush it and close it. That's all. No try/catch block has been defined for readability but the thrown exceptions should be caught.

Now let's execute it:

We should obtain this content:

There is also  which is a character counterpart of , and a destination counterpart to Reader, this is also an abstract superclass. Particular implementations parallel those of Reader, eg,  , and  , for converting a regular   into a reader so that it can take character data.

and
is a class in the package  with a number of static members that are available to Java programs. Two members that are useful for console output are  and. Both System.out and System.err are  objects. is a subclass of, itself a subclass of   (discussed above), and its main purpose is to translate a wide variety of data types into streams of bytes that represent that data in characters according to some encoding scheme.

and  both display text to a console where the user can read it, however what this means exactly depends on the platform used and the environment in which the program is running. In BlueJay and Eclipse IDE, for example, there is a special "terminal" window that will display this output. If the program is launched in Windows, the output will be sent to the DOS prompt (usually this means that you have to launch the program from the command line to see the output).

and  differ in what they're supposed to be used for. should be used for normal program output,  should be used to inform the user that some kind of error has occurred in the program. In some situations, this may be important. In DOS, for instance, a user can redirect standard output to some other destination (a file, for example), but error output will not be redirected, but rather displayed on the screen. If this weren't the case, the user might never be able to tell that an error had occurred.

New I/O
Versions of Java prior to J2SE 1.4 only supported stream-based blocking I/O. This required a thread per stream being handled, as no other processing could take place while the active thread blocked waiting for input or output. This was a major scalability and performance issue for anyone needing to implement any Java network service. Since the introduction of NIO (New I/O) in J2SE 1.4, this scalability problem has been rectified by the introduction of a non-blocking I/O framework (though there are a number of open issues in the NIO API as implemented by Oracle).

The non-blocking IO framework, though considerably more complex than the original blocking IO framework, allows any number of "channels" to be handled by a single thread. The framework is based on the Reactor Pattern.

More Info
More information on the contents of the  package can be viewed on the Oracle website by clicking this link (http://docs.oracle.com/javase/7/docs/api/index.html).

Java/Fluxos de entrada e saída