In Java, data is stored in big-endian format (also called network order). That is, all data is represented sequentially starting from the most significant bit to the least significant. JDK versions prior to JDK 1.4 required definition of custom methods that manage reversing byte order to maintain compatibility with little-endian systems. Correct handling of byte order–related issues is critical when exchanging data in a networked environment that includes both big-endian and little-endian machines or when working with other languages using Java Native Interface (JNI). Failure to handle byte-ordering issues can cause unexpected program behavior.
Noncompliant Code Example
The read methods (
readDouble()) and the corresponding write methods defined by class
java.io.DataInputStream and class
java.io.DataOutputStream operate only on big-endian data. Use of these methods while interoperating with traditional languages, such as C and C++, is insecure because such languages lack any guarantees about endianness. This noncompliant code example shows such a discrepancy:
Compliant Solution (
This compliant solution uses methods provided by class
ByteBuffer [API 2014] to correctly extract an
int from the original input value. It wraps the input byte array with a
ByteBuffer, sets the byte order to little-endian, and extracts the
int. The result is stored in the integer
ByteBuffer provides analogous get and put methods for other numeric types.
Compliant Solution (Define Special-Purpose Methods)
An alternative compliant solution is to define read and write methods that support the necessary byte-swapping while reading from or writing to the file. In this example, the
readLittleEndianInteger() method reads four bytes into a byte buffer and then pieces together the integer in the correct order. The
writeLittleEndianInteger() method obtains bytes by repeatedly casting the integer so that the least significant byte is extracted on successive right shifts.
Long values can be handled by defining a byte buffer of size 8.
Compliant Solution (
When programming for JDK 1.5 and later, use the
reverseBytes() method defined in the classes
Long to reverse the order of the integral value's bytes. Note that classes
Double lack such a method.
Reading and writing data without considering endianness can lead to misinterpretations of both the magnitude and sign of the data.
Automated detection is infeasible in the general case.
|Provide methods to read and write little-endian data
"On Holy Wars and a Plea for Peace"
Chapter 2, "Primitive Data Types, Cross-Platform Issues"