Home : Course Map : Chapter 9 : Java :
Converting Primitive Type Data to Bytes and Back
JavaTech
Course Map
Chapter 9

Introduction
Overview
Streams
Wrappers,Buffers
Console I/O
  Text Output 
     Demo 1

  Formatter/printf()
     Demo 2

  Tex 2t Input
     Demo 3

  Scanner
     
Demo 4
File Class
  File I/O
  File Output-Text
     Demo 5

  Formatter to File
     Demo 6

  File Input - Text
    Demo 7

  Scanner - Files
     Demo 8

  File I/O - Binary
     Demo 9
   Demo 10
File Chooser Dialog
  Demo 11

Character Codes
  Demo 12
   Demo13
Object I/O
Types to Bytes
Stream Filters
Other I/O Topics
Exercises

    Supplements
Character I/O
  Demo 1   Demo 2
Random Access
  Demo 3
ZIP/GZIP Streams
  Demo 4
Piped Streams
  Demo 5
NIO Framework
More NIO
  Demo 6

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

We have seen that Java is very strict with data types. Every data element must be explicitly assigned to a specific type. Casting can convert data of one type into another but a data value can never simultaneously act as more than one type. This differs from C/C++ where, say, a 32-bit integer type value can easily be accessed as two short values or four separate bytes.

For binary I/O with files as discussed previously, the underlying flow of data occurs as a sequence of bytes. We saw that by wrapping FileOutputStream with a DataOutputStream we obtained methods such as writeInt (int) and writeDouble (double) that put the bytes of wider types like int or double onto the outgoing stream.

Similarly, by wrapping a FileInputStream with a DataInputStream, the readInt() and readDouble() methods convert four bytes in the stream into an int value and eight bytes into a double value, respectively.

Note that on all platforms, Java uses the so-called big-endian representation. This means that for any primitive data value longer than one byte, the most significant byte is at the lowest address (i.e. big end first.) So, for example, in an output stream of int values, the high order byte goes out first and in an input stream the high order byte arrives first. This order is preserved by the JVM even on underlying platforms (such as Intel's) that use the reverse representation known as little-endian.

What if you obtain an array of bytes and need to extract data values of different types from it. For example, a byte array of 19 bytes might contain one char type, two int values, one double value, and one byte type. In C/C++ you can use memory pointers to reference different parts of the array and cast a group of bytes there to a particular type. In Java that type of direct memory referencing is not allowed.

Instead, you can make the array the source of a stream with the ByteArrayInputStream class. You then wrap this stream with DataInputStream and use its selection of methods for reading different data types. For example, to extract our data from the 19 elements of a byte array, we could use the following:

public void getData (byte[] data) {
  ByteArrayInputStream byte_in = new ByteArrayInputStream (data);
  DataInputStream data_in = new DataInputStream (byte_in);
  char c   = data_in.readChar ();
  int i    = data_in.readInt ();
  int j    = data_in.readInt ();
  double d = data_in.readDouble ();
  byte b   = data_in.readByte ();
  ...
}

Conversely, you can send a stream of data of different types to a ByteArrayOutputStream and then extract its internal byte array. It is convenient to wrap this stream with DataOutputStream, which provides a selection of methods for different types of such as writeInt (int), writeDouble (double), and writeChars().

ByteArrayOutputStream byte_out = new ByteArrayOutputStream ();
DataOutputStream data_out = new DataOutputStream (byte_out);

The byte array from the stream can be obtained with

byte_out.toByteArray ();

In Chapter 9: Tech we use these techniques for I/O with our histogram classes where we want to save a mix of data types into one big byte array. Also, in Chapter 23 we discuss serial I/O with a Java hardware processor that requires low level I/O with bytes. In an example program, we use a byte array streams to convert the a set of data bytes to wider types.

References & Web Resources

Latest update: August 18, 2005

              Tech
Histogram I/O
Hist I/O - Get/Set
  Demo 1
Hist I/O - Objects
  Demo 2
HistogramStream
  Demo 3
Filtering Data
  Demo 4
Exercises

           Physics
Physics Model
Simulation Design
Physics Simulator
  Demo 1
Experiment Design
Experiment Sim.
  Demo 2
Analysis
Expt. + Analysis
  Demo 3
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.