This Java File IO tutorial helps you understand and use the FileInputStream and FileOutputStream classes for manipulating binary files.

In Java, FileInputStream and FileOutputStream are byte streams that read and write data in binary format, exactly 8-bit bytes. They are descended from the abstract classes InputStream and OutputStream which are the super types of all byte streams.

The following class diagram helps you understand the API hierarchy of these byte stream classes:

ByteStreamsAPI

You can notice that these classes implement the AutoCloseable interface, which means that we can use the try-with-resources structure to close the streams automatically.

 

1. Understanding the FileInputStream Class

The FileInputStream is a byte input stream class that provides methods for reading bytes from a file. We can create an instance of this class by supplying a File or a path name, using these two constructors:

  • FileInputStream(File file)
  • FileInputStream(String name)

And the following list describes the key methods implemented by FileInputStream  class:

  • int available(): returns an estimate of the number of remaining bytes that can be read.
  • int read(): reads one byte of data, returns the byte as an integer value. Return -1 if the end of the file is reached.
  • int read(byte[]): reads a chunk of bytes to the specified byte array, up to the size of the array. This method returns -1 if there’s no more data or the end of the file is reached.
  • int read(byte[], int offset, int length): reads up to length bytes of data from the input stream.
  • long skip(long n): skips over and discards n bytes of data from the input stream. This method returns the actual number of bytes skipped.
  • FileChannel getChannel(): returns the unique FileChannel object associated with this file input stream. The FileChannel can be used for advanced file manipulation (New IO).
  • void close(): Closes this file input stream and releases any system resources associated with the stream.

Almost methods throw IOException so remember to handle or declare to throw it in your code.

 

2. Understanding the FileOutputStream Clas

The FileOutputStream is a byte output stream class that provides methods for writing bytes to a file. We can create an instance of this class by supplying a File or a path name, and/or specify to overwrite or append to an existing file, using the following constructors:

  • FileOutputStream(File file)
  • FileOutputStream(File file, boolean append): if append is true, then the bytes will be written to the end of an existing file rather than the beginning.
  • FileOutputStream(String name)
  • FileOutputStream(String name, boolean append)

And the following list describes the key methods implemented by FileOutputStream  class:

  • void write(int): writes the specified byte to the output stream.
  • void write(byte[]): writes the specified array of bytes to the output stream.
  • void write(byte[], int offset, int length): writes length bytes from the specified byte array starting at offset to the output stream.
  • FileChannel getChannel(): returns the unique FileChannel object associated with this file output stream. The FileChannel can be used for advanced file manipulation (New IO).
  • void close(): Closes this file output stream and releases any system resources associated with the stream.

Almost methods throw IOException so remember to handle or declare to throw it in your code.

Now, let’s see various code examples demonstrating the usages of the FileInputStream and FileOutputStream classes.

 

3. FileInputStream and FileOutputStream Examples

Example #1: Copy a File

The following program copies a file to another:

import java.io.*;

/**
 * This program demonstrates how to copy a file using the
 * FileInputStream and FileOutputStream classes with a
 * byte array as a buffer.
 * @author www.codejava.net
 */
public class CopyFile {
	private static final int BUFFER_SIZE = 4096;

    public static void main(String[] args) {
		if (args.length < 2) {
			System.out.println("Please provide input and output files");
			System.exit(0);
		}

		String inputFile = args[0];
		String outputFile = args[1];


        try (
			InputStream inputStream = new FileInputStream(inputFile);
			OutputStream outputStream = new FileOutputStream(outputFile);
        ) {

            byte[] buffer = new byte[BUFFER_SIZE];
			int bytesRead = -1;

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }
}

Run this program like this:

java CopyFile <source file> <dest file>

For example:

java CopyFile ByteStreamsAPI.png D:\ByteStreamsAPI.png

We can also copy a file using FileChannel in NIO like this:

import java.io.*;
import java.nio.channels.*;

/**
 * This program demonstrates how to copy a file using the
 * FileInputStream and FileOutputStream classes with FileChannel.s
 * @author www.codejava.net
 */
public class CopyFileChannel {

    public static void main(String[] args) {
		if (args.length < 2) {
			System.out.println("Please provide input and output files");
			System.exit(0);
		}

		String inputFile = args[0];
		String outputFile = args[1];

	    try (
			FileChannel sourceChannel = new FileInputStream(inputFile).getChannel();
			FileChannel destChannel = new FileOutputStream(outputFile).getChannel();
		) {
	        sourceChannel.transferTo(0, sourceChannel.size(), destChannel);
        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }
}

 

Example #2: Combine 2 files

The following program combines two files to the 3rd file:

import java.io.*;

/**
 * This program demonstrates how to combine two files to a 3rd file
 * using the FileInputStream and FileOutputStream classes.
 * @author www.codejava.net
 */
public class CombineFile {
	private static final int BUFFER_SIZE = 4096;

    public static void main(String[] args) {
		if (args.length < 3) {
			System.out.println("Please provide file1, file2, and output files");
			System.exit(0);
		}

		String inputFile1 = args[0];
		String inputFile2 = args[1];
		String outputFile = args[2];


        try (
			InputStream inputStream1 = new FileInputStream(inputFile1);
			InputStream inputStream2 = new FileInputStream(inputFile2);
			OutputStream outputStream = new FileOutputStream(outputFile);
        ) {

            byte[] buffer = new byte[BUFFER_SIZE];
			int bytesRead = -1;

            while ((bytesRead = inputStream1.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            while ((bytesRead = inputStream2.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }
}

Run this program like this:

java CombineFile <file1> <file2> <output file>

For example:

java CombineFile Sat.txt Sun.txt Weekend.txt

 

Example #3: Check file signature

The following program reads the first 4 bytes of a given file to check if it is a PDF document or not, based on the PDF file signature:

import java.io.*;
import java.util.*;

/**
 * This program demonstrates how to use the FileInputStream class to check
 * if a given file is actual a PDF file or not.
 * @author www.codejava.net
 */
public class CheckPDFFile {

    public static void main(String[] args) {
		if (args.length < 1) {
			System.out.println("Please provide the input file");
			System.exit(0);
		}

		String inputFile = args[0];

		byte[] pdfSignature = {37, 80, 68, 70};

        try (
			InputStream inputStream = new FileInputStream(inputFile);
        ) {
			byte[] header = new byte[4];
			inputStream.read(header);

			if (Arrays.equals(header, pdfSignature)) {
				System.out.println("It's a Real PDF file");
			} else {
				System.out.println("It's NOT a PDF file");
			}

        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }
}

Run this program like this:

java CheckPDFFile <file>

For example:

java JavaProjects.pdf

Output:

It's a Real PDF file

 

Example #4: Read File metadata

The following program reads the width and height of a PNG image file, according to PNG file format specification:

import java.io.*;
import java.util.*;
import java.math.*;

/**
 * This program demonstrates how to use the FileInputStream class to read
 * metadata of a PNG image file such as width and height.
 * @author www.codejava.net
 */
public class ReadPNGImage {

    public static void main(String[] args) {
		if (args.length < 1) {
			System.out.println("Please provide the input file");
			System.exit(0);
		}

		String inputFile = args[0];

		int[] pngSignature = {137, 80, 78, 71, 13, 10, 26, 10};
		byte[] ihdrSignature = {73, 72, 68, 82};

        try (
			InputStream inputStream = new FileInputStream(inputFile);
        ) {
			int[] pngHeader = new int[8];

			// read first 8 bytes as PNG file signature
			for (int i = 0; i < 8; i++) {
				pngHeader[i] = inputStream.read();
			}

			if (!Arrays.equals(pngHeader, pngSignature)) {
				System.out.println("The file is NOT a PNG image");
				System.exit(-1);
			}

			// skip next 4 bytes (chunk data length)
			inputStream.skip(4);

			// read next 4 bytes as IHDR header chunk
			byte[] ihdrHeader = new byte[4];
			inputStream.read(ihdrHeader);

			if (!Arrays.equals(ihdrHeader, ihdrSignature)) {
				System.out.println("Invalid IHDR header");
				System.exit(-1);
			}

			// read next 4 bytes as the width value
			byte[] bytes = new byte[4];
			inputStream.read(bytes);
			int width = new BigInteger(bytes).intValue();

			System.out.println("Width = " + width);

			// read next 4 bytes as the height value
			inputStream.read(bytes);
			int height = new BigInteger(bytes).intValue();

			System.out.println("Height = " + height);

        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }
}

Run this program like this:

java ReadPNGImage <file>

For example:

java ReadPNGImage ByteStreamsAPI.png

Output:

Width = 285
Height = 395

 

Example #5: Attach one file to another

The following program attaches content of a file to another:

import java.io.*;

/**
 * This program demonstrates how to attach one file at the end of another file
 * using the FileInputStream and FileOutputStream classes
 * @author www.codejava.net
 */
public class AttachFile {
	private static final int BUFFER_SIZE = 4096;

    public static void main(String[] args) {
		if (args.length < 2) {
			System.out.println("Please provide file1 and file2");
			System.exit(0);
		}

		String inputFile = args[0];
		String outputFile = args[1];


        try (
			InputStream inputStream = new FileInputStream(inputFile);
			OutputStream outputStream = new FileOutputStream(outputFile, true);
        ) {

            byte[] buffer = new byte[BUFFER_SIZE];
			int bytesRead = -1;

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

        } catch (IOException ex) {
			ex.printStackTrace();
		}
    }

}

Run this program like this:

java AttachFile <file1> <file2>

For example:

java AttachFile ByteStreamsAPI.png MDS.exe

This attaches an image file to the end of a Windows executable (EXE) file.

 

API References:

 

Related Java File IO Tutorial:

 

Other Java File IO Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment

   


Comments 

#1Fasikaw Kindye2019-01-04 14:09
very good tutorial
I like the short notes
Quote