ZetCode

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.

Main.java
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.

Main.java
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.

Main.java
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.

Main.java
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.

Main.java
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.

Main.java
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

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.