ZOFTINO.COM android and web dev tutorials

Java Input Output Byte Streams

Java input and output stream API provides classes to read data from any source and to write data to any destination. Data can be bytes, primitive types, localized characters and objects. Input source and output destinations can be disk file, network, memory arrays, string etc.

Java input and out stream classes provide the same interface to deal with different types of data and different source and destinations. These classes handle sequence of data one at a time. Let’s learn Java input output byte streams in this tutorial.

Table of Contents

Byte Streams

Byte streams are used to handle 8-bit bytes. Byte stream classes are subclasses of InputStream and OutputStream. Some of the subclasses of InputStream and OutputStream are ByteArrayInputStream, FileInputStream, FilterInputStream, and ObjectInputStream and ByteArrayOutputStream, FileOutputStream, FilterOutputStream, and ObjectOutputStream.

Some of the methods of InputStream are available(), mark(), read() , reset and skip(). Method available() allows you to get an estimate of the number of available bytes for reading. Method mark() can be used to mark the current position in the stream. Method read() allows you to read bytes from inputstream. Method reset allows you to reset the input stream position to the position which is set calling mark method. Method skip() allows you to skip and discard specified number of bytes.

InputStream provides overloaded read() methods using which you can read next byte of data from stream and read some number of bytes into an array of bytes.

Similarly, OutputStream provides methods such as write() for writing data to stream, flush() for making it write buffered data out, close() method for releasing resources. OutputStream provides overloaded write() methods using which you can write next byte of data to output stream and write some number of bytes from an array of bytes to output stream.

While dealing with byte streams, it is important to handle exceptions and close the stream objects to release resources.

ByteArrayInputStream Example

ByteArrayInputStream is used to create input stream with array of bytes as data source. It allows you to read bytes one after another. ByteArrayInputStream object is created by calling its constructor and passing byte array to it.

To learn how to use ByteArrayInputStream, let’s create a method which takes string as input and check whether the string contains discount percentage or not. It first converts the input string into byte array, then creates ByteArrayInputStream object by passing byte array. Then it reads each byte and returns true if the current byte is % and previous byte is a digit.

	public boolean isItPercentageDiscount(String offer) {
		byte[] offerBytes = offer.getBytes();
		ByteArrayInputStream byteStream = new ByteArrayInputStream(offerBytes);

		int byteC;
		int prevB=0;
		
		while(( byteC = byteStream.read())!= -1) {
			if(byteC == 37 && prevB > 47 && prevB < 58) {
				System.out.println("Offer has discount in the form of percentage");
				return true;
			}
			prevB = byteC;
		}
		return false;
	}

Call the method by passing offer strings which contain percentage discount and no percentage discount.

		boolean status = basu.isItPercentageDiscount("fashion upto 20% off");
		System.out.println("percentage discount offer: "+status);
		status = basu.isItPercentageDiscount("electronics flat 200 off");
		System.out.println("percentage discount offer: "+status);

Here is the output.

Offer has discount in the form of percentage
percentage discount offer: true
percentage discount offer: false

ByteArrayOutputStream Example

ByteArrayOutputStream is used to create output stream to which bytes of data can be written. To understand ByteArrayOutputStream, let’s create a method which writes text to ByteArrayOutputStream object and returns it.

	public ByteArrayOutputStream getOffersOutputStream() throws IOException {
		String offers= "upto 50% off on fashion,upto30% off on electronics";
		
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		outputStream.write(offers.getBytes());
		return outputStream;
	}

Caller of the methods gets the string from ByteArrayOutputStream.

		try {
			ByteArrayOutputStream bos = basu.getOffersOutputStream();
			System.out.println("offers : "+bos.toString());
		} catch (IOException e) {
			System.out.println("exception getting offers");
		}

Output :

offers : upto 50% off on fashion,upto30% off on electronics

FileInputStream Example

FileInputStream is a subclass of InputStream and is used to read bytes from a file. It is mainly used to read image files. FileInputStream object can be created using constructors which take file name string or file object.

After creating FileInputStream object, you can read a byte of data or read bytes of data into byte array using read methods.

public boolean isOffersFile(String file) {
	boolean status = false;
	try {
		InputStream fileInput = new FileInputStream(file);

		int dataBytes = fileInput.read();
		while(dataBytes != -1) {
			char dataChar = (char)dataBytes;
			if(dataChar == '%') {
				System.out.println("offer file contains discount in percentage");
				status = true;
			}
			dataBytes = fileInput.read();
		}
		fileInput.close();
	} catch (FileNotFoundException e) {
		System.out.println("file not found");
	} catch (IOException e) {
		System.out.println("input error");
	}
	return status;
}
		boolean offerFile = basu.isOffersFile(file);
		System.out.println("offer file : "+offerFile);

FileOutputStream Example

FileOutputStream is a subclass OutputStream and used for writing raw bytes to a file. FileOutputStream is mainly used for writing images to files. FileOutputStream is created using constructors which takes file name or file object as input.

Once FileOutputStream object is created, you can write to file each byte at a time by passing byte of data or array of bytes by passing byte array using write() methods.

public void writeToFile(String file, String[] data) throws IOException {
	OutputStream fileOutput = new FileOutputStream(file);
	
	for(String dataLine : data) {
		fileOutput.write(dataLine.getBytes());
		fileOutput.write(System.getProperty("line.separator").getBytes());
	}
	fileOutput.close();
}
		String offers[] = {"upto 10% off on mobiles", "flat 90% off on footwear"};
		
		try {
			basu.writeToFile(file, offers);
		} catch (IOException e1) {

		}

ObjectOutputStream Example

ObjectOutputStream can be used to write variables of primitive data types and objects to output stream. By writing objects to ObjectOutputStream, you can store objects in a file or transport over network. You can read previously written data and reconstruct objects using ObjectInputStream. The process of writing objects to ObjectOutputStream is called serialization and reading from ObjectInputStream is called deserialization.

To be able to write an object to ObjectOutputStream, the class of the object must implement Serializable interface. The default serialization mechanism for objects writes values of all non transient and non static fields of the object. You can customize serialization and deserialization by overriding readObject() and writeObject() methods. To have complete control over the process, you need to implement Externalizable interface.

To write primitive data to ObjectOutputStream, you can use corresponding write method for the data type such as writeInt(), writeFloat(), writeDouble(), writeBoolean(), writeChar(), etc. For example, to write String to output stream, you can use writeObject method. Using FileOutputStream, you can save data written to ObjectOutputStream to a file.

String offer = "flat 33% off on everything";
try {
	ObjectOutputStream outputStream =
	        new ObjectOutputStream(new FileOutputStream(file));

	outputStream.writeObject(offer);
	outputStream.close();
} catch (Exception ex) {
	System.out.println("Exception writing to file");
} 

Below example shows saving custom object to a file using ObjectOutputStream and FileOutputStream.

public void writeObjectToFile(Product prd, String file) throws IOException {		
	ObjectOutputStream outputStream =
            new ObjectOutputStream(new FileOutputStream(file));

	outputStream.writeObject(prd);
	outputStream.close();
}
public class Product implements Serializable{

	private static final long serialVersionUID = 1L;
	private int prodId;
	private String name;
	private String brand;
	private double price;
	
	public int getProdId() {
		return prodId;
	}
	public void setProdId(int prodId) {
		this.prodId = prodId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	
}
		Product prd =  new Product();
		prd.setProdId(343);
		prd.setBrand("Apple");
		prd.setName("IPhone 8");
		prd.setPrice(500);
		
		try {
			basu.writeObjectToFile(prd, file);
		} catch (IOException ex) {
			System.out.println("Exception writing to file");
			ex.printStackTrace();
		}

ObjectInputStream Exampler

ObjectInputStream can be used to read variables of primitive data types and objects previously written using ObjectOutputStream.

ObjectInputStream can handle primitive data types and objects of classes which implement Serializable interface or Externalizable interface. The default deserialization mechanism reads all non transient and non static fields of the object and reconstructs it. You can customize deserialization by overriding readObject() method. To have complete control over the process, you need to implement Externalizable interface.

To read primitive data, you can use corresponding read method for the data type such as readInt(), readFloat(), readDouble(), readBoolean(), readChar(), etc. For example, to read String, you can use readObject method. Using FileInputStream and ObjectInputStream , you can read the data written to a file and reconstruct objects.

		try {
			ObjectInputStream outputStream =
		            new ObjectInputStream(new FileInputStream(file));

			String deal = (String)outputStream.readObject();
			System.out.println("from file "+deal);
			outputStream.close();
		} catch (Exception ex) {
			System.out.println("Exception reading from file");
		} 

Below example shows deserialization of a custom object which is previously serialized to a file.

public Product readObjectFromFile(String file) throws Exception {		
	ObjectInputStream outputStream =
            new ObjectInputStream(new FileInputStream(file));

	Product prd = (Product)outputStream.readObject();
	outputStream.close();
	return prd;
}
		try {
			Product p = basu.readObjectFromFile(file);
			System.out.println(""+p.getName());
		} catch (Exception ex) {
			System.out.println("Exception reading from file");
			ex.printStackTrace();
		}

SequenceInputStream Example

SequenceInputStream object allows you to logically concatenate multiple input streams. You can read data continuously from all the supplied input streams. You can create SequenceInputStream object by passing two input streams or enumeration of input streams to its constructors.

try {
	InputStream fileInputOne = new FileInputStream(file);
	InputStream fileInputTwo = new FileInputStream(fileTwo);
	
	InputStream sequenceIS = new SequenceInputStream(fileInputOne, fileInputTwo);
	
	int dataBytes = sequenceIS.read();
	while(dataBytes != -1) {
		char dataChar = (char)dataBytes;
		System.out.println(dataChar);
		dataBytes = sequenceIS.read();
	}
	sequenceIS.close();
	
} catch (Exception e) {
	System.out.println("Exception reading files");
}

BufferedInputStream Example

BufferedInputStream enhances other input streams by buffering bytes and providing mark and reset functionality. BufferedInputStream makes reading bytes from other streams especially FileInputStream efficient because read() method call doesn’t always result in reading from source as it uses buffer.

BufferedInputStream object is created by calling its constructor and passing instance of another input stream object.

	try {
		FileInputStream fis = new FileInputStream(file);
		BufferedInputStream bis = new BufferedInputStream(fis);
		
		int b;
		while((b= bis.read()) != -1) {
			System.out.print((char)b);
		}
		bis.close();
	} catch (IOException e) {

	}

BufferedOutputStream Example

BufferedOutputStream enhances other output streams by using buffer. Method calls to write() on BufferedOutputStream do not always result in writing bytes to destination as it uses buffer to store bytes. You can create BufferedOutputStream by calling its constructor and passing another output stream to as an argument it.

	try {
		FileOutputStream fos = new FileOutputStream(file);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		String offer = "cashback upto 4% on fashion";			
		bos.write(offer.getBytes());
		bos.write(System.lineSeparator().getBytes());
		
		offer = "get flat 10% off on electronics";			
		bos.write(offer.getBytes());
		bos.write(System.lineSeparator().getBytes());
		
		bos.flush();
		
		offer = "get flat 20% off on shoes";			
		bos.write(offer.getBytes());
		bos.write(System.lineSeparator().getBytes());
		
		bos.close();
		
	} catch (IOException e) {

	}

DataOutputStream Example

DataOutputStream enhances output streams by provide functionality to write primitive data types in a portable way or machine independent way. You can create an instance of DataOutputStream by calling its constructor and passing output stream as an argument to it.

DataOutputStream provides methods to write primitive data such as writeInt, writeBoolean, writeShort, writeFloat, writeLong, writeDoublet, etc.

	try {
		FileOutputStream fos = new FileOutputStream(file);
		DataOutputStream dos = new DataOutputStream(fos);
		
		int intval = 33;
		dos.writeInt(intval);
		
		boolean boolVal = true;
		dos.writeBoolean(boolVal);
		
		double doubleVal = 44.44;
		dos.writeDouble(doubleVal);
		
		dos.writeBytes("hello");
		
		dos.close();
	} catch (IOException e) {

	}

DataInputStream Example

DataInputStream allows you to read primitive data in a portable way from another stream. DataInputStream is used to read data written using DataOutputStream. DataInputStream is created by calling its constructor and passing an input stream to it.

DataInputStream provides methods to read primitive data such as reading, readShort, readFloat, readDoublet, readBoolean, etc.

	try {
		FileInputStream fis = new FileInputStream(file);
		DataInputStream dis = new DataInputStream(fis);
		
		System.out.print(dis.readInt());
		System.out.print(dis.readBoolean());
		System.out.print(dis.readInt());
		System.out.print(dis.readDouble());
		
		dis.close();
	} catch (IOException e) {

	}

Other Tutorials Related to Java IO