o7planning

Java InputStream Tutorial

View more Tutorials:

1- InputStream

InputStream is a class in java.io package, which is a base class representing a stream of bytes, obtained when reading a certain data source, such as file.
public abstract class InputStream implements Closeable
Basically, you cannot use InputStream class directly because it is an abstract class, but in a particular case you can use one of its subclasses.
Let's see an example of an UTF-8 encoded text file:
utf8-file-without-bom.txt
JP日本-八洲
UTF-8 uses 1, 2, 3 or 4 bytes to store a character. The image below shows the bytes in the aforementioned file.
FileInputStream is a subclass of InputStream, which is commonly used to read files and we get a stream of bytes.
InputStream Methods
public static InputStream nullInputStream()

public abstract int read() throws IOException  

public int read(byte[] b) throws IOException  
public int read(byte[] b, int off, int len) throws IOException

public byte[] readAllBytes() throws IOException
public byte[] readNBytes(int len) throws IOException  
public int readNBytes(byte[] b, int off, int len) throws IOException  

public long skip(long n) throws IOException  
public int available() throws IOException  

public void close() throws IOException  
public synchronized void mark(int readlimit)  
public synchronized void reset() throws IOException  

public boolean markSupported()  
public long transferTo(OutputStream out) throws IOException

2- read()

public int read() throws IOException  
read() method is used to read a byte. Value of the returned byte is an integer between 0 and 255, or returns -1 if it has reached the end of the stream.
This method will block until byte is available to read or an IO error occurs, or has reached the end of the stream.
utf8-file-without-bom.txt
JP日本-八洲
Example:
InputStream_read_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_read_ex1 {
    
    // Windows path: C:/somepath/utf8-file-without-bom.txt"
    private static final String filePath = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        // FileInputStream is a subclass of InputStream.
        InputStream is = new FileInputStream(filePath);

        int code;
        while((code = is.read()) != -1) {
            System.out.println(code + " " + (char)code);
        }
        is.close();
    }
}
Output:
74 J
80 P
230 æ
151 —
165 ¥
230 æ
156 œ
172 ¬
45 -
229 å
133 …
171 «
230 æ
180 ´
178 ²

3- read(byte[])

public int read(byte[] b) throws IOException  
read(byte[]) method reads bytes from InputStream and assigns to the elements of the array and returns the number of bytes just read. This method returns -1 if it has reached the end of the stream.
This method will block until the bytes is available to read or an IO error occurs, or has reached the end of the stream.
Basically, using read(byte[]) method will have higher performance than read() method, since it reduces the number of times it needs to read from the stream.
InputStream_read_ex2.java
package org.o7planning.inputstream.ex;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class InputStream_read_ex2 {

    public static void main(String[] args) throws IOException {
        String url = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";

        InputStream is = new URL(url).openStream();

        // Create a temporary byte array.
        byte[] tempByteArray = new byte[10];
        int byteCount = -1;

        int nth = 0;
        while ((byteCount = is.read(tempByteArray)) != -1) {
            nth++;
            System.out.println("--- Read th: " + nth + " ---");
            System.out.println(" >> Number of bytes read: " + byteCount +"\n");
            
            for(int i= 0; i < byteCount; i++) {
                // bytes are in range [-128,127]
                // Convert byte to unsigned byte. [0, 255].
                int code = tempByteArray[i] & 0xff;
                
                System.out.println(tempByteArray[i] + "    " + code + "    " + (char)code);
            }
        }
        is.close();
    }
}
Output:
--- Read th: 1 ---
 >> Number of bytes read: 10

74    74    J
80    80    P
-26    230    æ
-105    151    —
-91    165    ¥
-26    230    æ
-100    156    œ
-84    172    ¬
45    45    -
-27    229    å
--- Read th: 2 ---
 >> Number of bytes read: 5

-123    133    …
-85    171    «
-26    230    æ
-76    180    ´
-78    178    ²
Note: The byte data type includes integers in the range from -128 to 127. You can convert it to an unsigned integer with the range from 0 to 255.

4- read(byte[], int, int)

public int read(byte[] b, int offset, int len) throws IOException  
read(byte[],int,int) method reads bytes and assigns to elements of array from offset index to offset+len index, and returns the number of bytes just read. This method returns -1 if it has reached the end of the stream.
This method will block until the bytes are available for reading, or an IO error occurs, or has reached the end of the stream.

5- readAllBytes()

public byte[] readAllBytes() throws IOException
Example:
InputStream_readAllBytes_ex1.java
package org.o7planning.inputstream.ex;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class InputStream_readAllBytes_ex1 {

    public static void main(String[] args) throws IOException {
        String url = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";

        InputStream is = new URL(url).openStream();

        byte[] allBytes = is.readAllBytes();
        String content = new String(allBytes, "UTF-8");
        System.out.println(content);

        is.close();
    }
}
Output:
JP日本-八洲

6- readNBytes(int len)

public byte[] readNBytes(int len) throws IOException  
readNBytes(int) method reads up to "len" bytes from InputStream, and returns a byte array read. If the returned array is empty, it is already at the end of the stream.
This method will block until "len" bytes have been read, or an IO error occurs, or has reached the end of the stream.
Example:
InputStream_readNBytes_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_readNBytes_ex1 {
    
    // Windows path: C:/somepath/utf8-file-without-bom.txt"
    private static final String filePath = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        // FileInputStream is a subclass of InputStream.
        InputStream is = new FileInputStream(filePath);

        byte[] bytes = null;
        int nth = 0;
        while( true) {
            nth++;
            bytes = is.readNBytes(10);
            
            System.out.println("--- Read th: " + nth + " ---");
            System.out.println(" >> Number of bytes read: " + bytes.length +"\n");
            
            
            if(bytes.length == 0) {
                break;
            }
            for(int i= 0; i< bytes.length; i++) {
                // bytes are in range [-128,127]
                // Convert byte to unsigned byte. [0, 255].
                int code = bytes[i] & 0xff;
                
                System.out.println(bytes[i] + "    " + code + "    " + (char)code);
            }
        }
        is.close();
    }
}
Output:
--- Read th: 1 ---
 >> Number of bytes read: 10

74    74    J
80    80    P
-26    230    æ
-105    151    —
-91    165    ¥
-26    230    æ
-100    156    œ
-84    172    ¬
45    45    -
-27    229    å
--- Read th: 2 ---
 >> Number of bytes read: 5

-123    133    …
-85    171    «
-26    230    æ
-76    180    ´
-78    178    ²
--- Read th: 3 ---
 >> Number of bytes read: 0

7- readNBytes(byte[] b, int off, int len)

public int readNBytes(byte[] b, int offset, int len) throws IOException  
readNBytes(byte[],int,int) method reads up to "len" bytes from InputStream, and assigns read bytes to array elements from offset index to offset+len index, and returns the number of read bytes. Returns -1 if it has reached the end of the stream.

read(byte[],int,int) vs readNBytes(byte[],int,int)

public int read(byte[] b, int offset, int len) throws IOException  

public int readNBytes(byte[] b, int offset, int len) throws IOException  
The two methods read(byte[],int,int) and readNBytes(byte[],int,int) are quite similar. But there is a difference in the following situation:
read(byte[] b,int offset,int len) method does not guarantee that "len" bytes to be read from the stream even though it has not reached the end of the stream yet.
readNBytes(byte[] b,int offset,int len) method guarantees that "len" bytes to be read from the stream if it hasn't reached the end of the stream yet.

8- close()

public void close() throws IOException  
Closes the stream and releases any system resources associated with it. Once the stream has been closed, further read(), mark(), reset(), or skip() invocations will throw an IOException. Closing a previously closed stream has no effect.
public interface Closeable extends AutoCloseable
The InputStream class implements Closeable interface. If you write code according to the rules of AutoCloseable, the system will automatically close the stream for you without having to call close() method directly.
InputStream_close_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_close_ex1 {
    
    // Or Windows path: C:/Somefolder/utf8-file-without-bom.txt
    private static final String file_path = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        
        // (InputStream class implements Closeable)
        // (Closeable interface extends AutoCloseable)
        // try block will automatically close stream for you.
        try (InputStream fileInputStream= new FileInputStream(file_path)) {
            int code;
            while((code = fileInputStream.read()) !=  -1)  {
                System.out.println(code +"  " + (char)code);
            }  
        } // end try
    }
}
  • TODO Link?

9- skip(long)

public long skip(long n) throws IOException  
skip(long) method skips "n" bytes.
This method will block until bytes are available or an IO error occurs, or has reached the end of the stream.
InputStream_skip_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_skip_ex1 {

    public static void main(String[] args) throws IOException {
        
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes();
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream is = new ByteArrayInputStream(bytes);

        int firstByteCode = is.read();
        int secondByteCode = is.read();

        System.out.println("First byte: " + (char) firstByteCode);
        System.out.println("Second byte: " + (char) secondByteCode);

        is.skip(18); // Skips 18 bytes.

        int code;
        while ((code = is.read()) != -1) {
            System.out.println(code +" " + (char) code);
        }
        is.close();
    }
}
Output:
First byte: 1
Second byte: 2
65 A
66 B
67 C
68 D
69 E

10- transferTo(OutputStream)

// Java 10+
public long transferTo(OutputStream out) throws IOException
The transferTo(OutputStream) method is used to read all bytes from the current InputStream and write them to the specified OutputStream object, and return the number of bytes transferred to OutputStream. Once done, the current InputStream object will be at the end of the stream. This method will not close the current InputStream object nor the OutputStream object.
InputStream_transferTo_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class InputStream_transferTo_ex1 {

    public static void main(String[] args) throws IOException {
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes();
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream reader = new ByteArrayInputStream(bytes);

        // Or Windows path: C:/Somepath/out-file.txt
        File file = new File("/Volumes/Data/test/out-file.txt");
        // Create parent folder.
        file.getParentFile().mkdirs();

        OutputStream writer = new FileOutputStream(file);

        reader.skip(10); // Skips 10 bytes.

        reader.transferTo(writer);

        reader.close();
        writer.close();
    }
}
Output:
out-file.txt
987654321-ABCDE
  • TODO Link?

11- markSupported()

public boolean markSupported()  
markSupported() method is used to check if the current InputStream object supports mark(int) operation. (See also mark(int) method)

12- mark(int)

public void mark(int readAheadLimit) throws IOException  
mark(int) method allows you to mark the current position on the stream. You can read the next bytes, and call reset() method to return to the position marked before, in which readAheadLimit is the maximum number of bytes that can read after marking without losing the marked position.
Note: Not all InputStreams support mark(int) operation. To be sure you need to call markSupported() method to check if the current InputStream object supports that operation.
InputStream_mark_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_mark_ex1 {

    public static void main(String[] args) throws IOException {
        
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes(); // byte[]{'1','2', .... 'E'}
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream is = new ByteArrayInputStream(bytes);


        is.skip(10); // Skips 10 bytes.

        System.out.println("ByteArrayInputStream markSupported? " + is.markSupported()); // true
        
        is.mark(9);
        
        int code1 = is.read();
        int code2 = is.read();
        
        System.out.println(code1 + "  " + (char) code1); // '9'
        System.out.println(code2 + "  " + (char) code2); // '8'
        is.skip(5);
        
        System.out.println("Reset");
        is.reset(); // Return to the marked position.
        
        int code;
        while((code = is.read())!= -1) {
            System.out.println(code + "  " + (char)code);
        }
        is.close();
    }
}
Output:
ByteArrayInputStream markSupported? true
57  9
56  8
Reset
57  9
56  8
55  7
54  6
53  5
52  4
51  3
50  2
49  1
45  -
65  A
66  B
67  C
68  D
69  E

13- reset()

public void reset() throws IOException  
If this InputStream object supports marking the current position via the mark(int) method, then reset() method is used to return the marked position.

View more Tutorials:

Maybe you are interested

These are online courses outside the o7planning website that we introduced, which may include free or discounted courses.