Filter Streams   «Prev  Next»

Lesson 11Treating arrays as input streams
ObjectiveLearn to Read Data from a Byte Array in Java .

Read Data from byte Array in Java

It is sometimes convenient to use streams methods to read from a byte array.
For example, you might receive an array of raw bytes over the network that you want to interpret as double-precision floating point numbers.


Treating Arrays as Input Streams

Unlike the more common TCP data, which acts like the streams we are discussing in this course, UDP data arrives in raw packets of bytes, which do not necessarily have any relation to the previous packet or the next packet. Each packet is just a group of bytes to be processed in isolation from other packets. Thus you may get nothing for several seconds, or even minutes, and then suddenly have a few hundred numbers to deal with.
In Java, UDP data is sent and received via the java.net.DatagramSocket and java.net.DatagramPacket classes. The receive() method of the java.net.DatagramSocket class returns its data in a DatagramPacket, which is little more than a wrapper around a byte array. This byte array can be easily used as the source of a ByteArrayInputStream .

Java Stream Methods

It is sometimes convenient to use stream methods to manipulate data in byte arrays. For example, you might receive an array of raw bytes that you want to interpret as double precision, floating-point numbers. (This is common when using UDP to transfer data across the Internet, for one example.) The quickest way to do this is to use a DataInputStream. However, before you can create a data input stream, you first need to create a raw, byte-oriented stream.
This is what the java.io.ByteArrayInputStream class gives you. Similarly, you might want to send a group of
  1. double-precision,
  2. floating-point numbers
across the network with UDP. Before you can do this, you have to convert the numbers into bytes.
The simplest solution is to use a data output stream chained to a java.io.ByteArrayOutputStream. By chaining the data output stream to a byte array output stream, you can write the binary form of the floating-point numbers into a byte array, then send the entire array in a single packet.

Input streams

Class java.io.InputStream is an abstract base class for all the input streams in Java. It is extended by all the classes that need to read bytes (for example, image data) from multiple data sources. Let us start with the most important method of this class, read(), used to read data from a source. The class InputStream defines multiple overloaded versions of method read(), which can be used to read a single byte of data as int, or multiple bytes into a byte array:

int abstract read()
int read(byte[] b)
int read(byte[] b, int off, int len)

But you would not use these methods yourself. You would use method read() by more specific classes that extend the abstract class InputStream. For example, class File-InputStream extends InputStream and overrides its read() method for you to use.
Watch out for the use of method read() from class Input-Stream. It returns the next byte of data, or -1 if the end of the stream is reached. It does not throw an EOFException. Method close() is another important method of class InputStream. Calling close() on a stream releases the system resources associated with it. Because InputStream is an abstract class, you cannot create an instance to read from a data source or destination. You need one of its subclasses to do the work for you. So why do you need to bother with so much theory about it?

Why do you need to bother with so much theory on InputStream?

On the Java Certification exam, you will be tested on whether you can call a particular method on an object. For example, you might be tested on whether you can call the method read() or close() on an object of, say, FileInputStream, a subclass of InputStream.Because methods read() and close() are defined in class InputStream, they can be called on objects of any derived classes of InputStream.These might not be straightforward questions. You need to get the hang of the basics to answer them correctly.
The quickest way to do this is to use a DataInputStream. However, before you can create a data input stream, you first need to create a raw, byte-oriented stream. This is what the java.io.ByteArrayInputStream class gives you. Byte array input streams are also commonly used when sending and receiving UDP data over the Internet.
There are two polymorphic ByteArrayInputStream constructors.
Both take a byte array as an argument. This byte array is the buffer from which data will be read.
Other than these two constructors, the ByteArrayInputStream class just has the usual read(), available(), close(), mark(), and reset() methods. Byte array input streams do support marking and resetting.

Java Lambdas and Parallel Streams