Java ByteArrayInputStream Class
Last modified: April 16, 2025
The java.io.ByteArrayInputStream
class allows reading bytes from a
byte array as an input stream. It's part of Java's I/O package and provides an
in-memory stream implementation. This class is useful when working with byte
arrays as streams.
ByteArrayInputStream
extends InputStream
and wraps a
byte array. It maintains an internal position counter to track reading progress.
The stream can be reset to re-read data. Unlike file streams, it doesn't need
external resources.
ByteArrayInputStream Class Overview
ByteArrayInputStream
provides stream functionality for byte arrays.
Key methods include standard read operations, mark/reset, and stream skipping.
The class doesn't require closing but implements Closeable for compatibility.
public class ByteArrayInputStream extends InputStream { public ByteArrayInputStream(byte[] buf); public ByteArrayInputStream(byte[] buf, int offset, int length); public synchronized int read(); public synchronized int read(byte[] b, int off, int len); public synchronized long skip(long n); public synchronized int available(); public synchronized void mark(int readAheadLimit); public synchronized void reset(); public boolean markSupported(); public void close(); }
The code above shows key methods of ByteArrayInputStream
. The class
supports all standard InputStream operations. Mark/reset functionality is always
available. The buffer is not copied, just referenced by the stream.
Creating a ByteArrayInputStream
ByteArrayInputStream is created by passing a byte array to its constructor. You can specify the entire array or a portion. The stream operates on the original array - changes to the array affect the stream.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { byte[] data = {65, 66, 67, 68, 69, 70}; // A-F in ASCII // Create stream from full array ByteArrayInputStream stream1 = new ByteArrayInputStream(data); // Create stream from portion (bytes 2-4) ByteArrayInputStream stream2 = new ByteArrayInputStream(data, 2, 3); try { System.out.println("Stream1 contents:"); while (stream1.available() > 0) { System.out.print((char) stream1.read() + " "); } System.out.println("\n\nStream2 contents:"); while (stream2.available() > 0) { System.out.print((char) stream2.read() + " "); } } catch (IOException e) { e.printStackTrace(); } } }
This example shows two ways to create ByteArrayInputStream. The first uses the entire array, while the second uses a portion. The output shows the different contents. Note that IOException is unlikely but must be handled.
Reading Single Bytes
The simplest way to read from ByteArrayInputStream is byte by byte. The read method returns -1 at end of stream. Each call advances the internal position. This approach is simple but not efficient for large data.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String text = "Hello ByteArrayInputStream"; byte[] bytes = text.getBytes(); try (ByteArrayInputStream stream = new ByteArrayInputStream(bytes)) { int byteData; System.out.println("Reading bytes:"); while ((byteData = stream.read()) != -1) { System.out.print((char) byteData + "(" + byteData + ") "); } System.out.println("\n\nReading complete"); } catch (IOException e) { e.printStackTrace(); } } }
This example reads a string as bytes from ByteArrayInputStream. Each byte is printed as both character and numeric value. The try-with-resources ensures proper stream closure. Though not required for ByteArrayInputStream, it's good practice.
Reading Bytes into an Array
For better performance, read multiple bytes at once into a byte array. This reduces method calls and is more efficient. The read method returns the count of bytes actually read.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String text = "Reading bytes in bulk is more efficient"; byte[] source = text.getBytes(); try (ByteArrayInputStream stream = new ByteArrayInputStream(source)) { byte[] buffer = new byte[10]; int bytesRead; System.out.println("Reading in chunks:"); while ((bytesRead = stream.read(buffer)) != -1) { String chunk = new String(buffer, 0, bytesRead); System.out.println("Read " + bytesRead + " bytes: " + chunk); } } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates bulk reading into a 10-byte buffer. The String constructor converts each chunk to text. The bytesRead value ensures only actual data is processed. This approach is much faster for large data sets.
Mark and Reset Functionality
ByteArrayInputStream fully supports mark and reset operations. The mark method remembers the current position. Reset returns to this position, allowing data re-reading. The readAheadLimit parameter is ignored.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; try (ByteArrayInputStream stream = new ByteArrayInputStream(data)) { // Read first 3 bytes System.out.println("First 3 bytes:"); for (int i = 0; i < 3; i++) { System.out.print(stream.read() + " "); } // Mark current position stream.mark(100); // Parameter is ignored // Read next 3 bytes System.out.println("\n\nNext 3 bytes:"); for (int i = 0; i < 3; i++) { System.out.print(stream.read() + " "); } // Reset to mark stream.reset(); // Read again from mark System.out.println("\n\nAfter reset, next 3 bytes:"); for (int i = 0; i < 3; i++) { System.out.print(stream.read() + " "); } } catch (IOException e) { e.printStackTrace(); } } }
This example shows mark/reset functionality. After reading 3 bytes, we mark the position. After reading 3 more bytes, reset returns to the mark. The readAheadLimit parameter is ignored in ByteArrayInputStream.
Skipping Bytes in the Stream
The skip method moves the stream position forward without reading. It returns the actual number of bytes skipped. This is more efficient than reading and discarding data.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; byte[] bytes = text.getBytes(); try (ByteArrayInputStream stream = new ByteArrayInputStream(bytes)) { System.out.println("Initial position: " + stream.available()); // Skip first 5 bytes long skipped = stream.skip(5); System.out.println("Skipped " + skipped + " bytes"); System.out.println("Next byte: " + (char) stream.read()); // Try to skip beyond end skipped = stream.skip(20); System.out.println("Skipped " + skipped + " bytes (end approached)"); System.out.println("Remaining: " + stream.available()); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates skipping bytes. The first skip moves past the first 5 letters. The second attempts to skip 20 bytes but only skips remaining bytes. The available method shows bytes left to read.
Available Bytes and Position
The available method returns remaining bytes in the stream. This is useful for checking stream status. ByteArrayInputStream also provides position tracking through this method.
import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { byte[] data = new byte[100]; for (int i = 0; i < data.length; i++) { data[i] = (byte) i; } try (ByteArrayInputStream stream = new ByteArrayInputStream(data)) { System.out.println("Initial available: " + stream.available()); // Read 10 bytes byte[] buffer = new byte[10]; stream.read(buffer); System.out.println("After reading 10 bytes: " + stream.available()); // Skip 20 bytes stream.skip(20); System.out.println("After skipping 20 bytes: " + stream.available()); // Read remaining while (stream.available() > 0) { stream.read(buffer); System.out.println("Read 10 bytes, remaining: " + stream.available()); } } catch (IOException e) { e.printStackTrace(); } } }
This example tracks stream position using available. After each operation, the remaining bytes decrease. The method provides an exact count for ByteArrayInputStream. This differs from other streams where available is an estimate.
Source
Java ByteArrayInputStream Class Documentation
In this article, we've covered the essential methods and features of the Java ByteArrayInputStream class. Understanding these concepts is crucial for working with in-memory byte data as streams in Java applications.
Author
List all Java tutorials.