Java 11 - New Methods in java.io

In this article we will go through new methods for java.io package added in Java 11. There are null InputStream/OutputStream/Reader/Writer, InputStream readNBytes(...), and new Constructors for FileReader and FileWriter.

Null InputStream/OutputStream/Reader/Writer

Java 11 added new methods which return streams that represent disabled input/output. These functions is like /dev/null for throwing away output that we don’t need or providing an input that always returns zero bytes or no characters:

  • java.io.InputStream nullInputStream(): Returns an InputStream that reads no bytes.
  • java.io.OutputStream nullOutputStream(): Returns a new OutputStream which discards all bytes.
  • java.io.Reader nullReader(): Returns a new Reader that reads no characters.
  • java.io.Writer nullWriter(): Returns a new Writer which discards all characters.

We can use those functions like /dev/null for throwing away output that we don’t need or providing an input that always returns zero bytes or no characters.

nullInputStream()

NullInputStream.java
package com.dariawan.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;

public class NullInputStream {

    static void printInputStream(InputStream inputStream) throws IOException {
        System.out.printf("inputStream type: [%s] %s%n",
                inputStream.getClass().getSimpleName(),
                inputStream.toString());
    }

    public static void main(String[] args) throws IOException {
        var classLoader = ClassLoader.getSystemClassLoader();
        var inputStream1 = InputStream.nullInputStream();  // new method
        var inputStream2 = classLoader.getResourceAsStream("test.txt");

        File fstream = File.createTempFile("test", ".out");
        fstream.deleteOnExit();
        
        try (OutputStream outputStream = new FileOutputStream(fstream)) {
            inputStream1.transferTo(outputStream);
            outputStream.flush();

            inputStream2.transferTo(outputStream);
        }

        printInputStream(inputStream1);
        printInputStream(inputStream2);

        var path = fstream.toPath();
        System.out.println(path);
        System.out.println(Files.readString(path));
    }
}
                    

inputStream type: [] [email protected] inputStream type: [BufferedInputStream] [email protected] C:\Users\Desson\AppData\Local\Temp\test16024816594492158875.out This is test file...

nullOutputStream()

NullOutputStream.java
package com.dariawan.io;

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

public class NullOutputStream {

    static void printOutputStream(OutputStream outputStream) {
        System.out.printf("outputStream type: [%s] %s%n",
                outputStream.getClass().getSimpleName(),
                outputStream.toString());
    }

    public static void main(String[] args) throws IOException {
        var classLoader = ClassLoader.getSystemClassLoader();
        var inputStream = classLoader.getResourceAsStream("test.txt");

        File fstream = File.createTempFile("test", ".out");
        fstream.deleteOnExit();
        
        try (OutputStream outputStream = new FileOutputStream(fstream)) {
            inputStream.transferTo(outputStream);
            printOutputStream(outputStream);
        }

        try (OutputStream outputStream = OutputStream.nullOutputStream()) {
            inputStream.transferTo(outputStream);
            printOutputStream(outputStream);
        }
    }
}
                    

outputStream type: [FileOutputStream] [email protected] outputStream type: [] [email protected]

nullReader()

NullReader.java
package com.dariawan.io;

import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.Reader;

public class NullReader {

    static void printReader(Reader reader) throws IOException {
        System.out.printf("reader type: [%s] %s%n",
                reader.getClass().getSimpleName(),
                reader.toString());
    }

    public static void main(String[] args) throws IOException {
        var charArr = new char[]{'D', 'a', 'r', '1', 'a', 'w', 'a', 'n'};

        var reader1 = Reader.nullReader(); //new method
        var reader2 = new CharArrayReader(charArr);

        try (CharArrayWriter writer = new CharArrayWriter()) {
            reader1.transferTo(writer);
            System.out.println(writer.size());

            reader2.transferTo(writer);
            System.out.println(writer.size());
        }
        printReader(reader1);
        printReader(reader2);
    }
}
                    

0 8 reader type: [] [email protected] reader type: [CharArrayReader] [email protected]

nullWriter()

NullWriter.java
package com.dariawan.io;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.Writer;

public class NullWriter {

    static void printWriter(Writer writer) {
        System.out.printf("writer type: [%s] %s%n",
                writer.getClass().getSimpleName(),
                writer.toString());
    }

    public static void main(String[] args) throws IOException {
        var reader = new StringReader("test string reader");
        File fout = File.createTempFile("test", ".out");
        fout.deleteOnExit();
        
        try (PrintWriter writer = new PrintWriter(fout)) {
            reader.transferTo(writer);
            printWriter(writer);
        }

        try (java.io.Writer writer = Writer.nullWriter()) {
            reader.transferTo(writer);
            printWriter(writer);
        }
    }
}
                    

writer type: [PrintWriter] [email protected] writer type: [] [email protected]

InputStream readNBytes(int len)

function readNBytes(byte[] b, int off, int len) is already available for java.io.InputStream since Java 9, but Java 11 added a new method:

  • byte[] readNBytes(int len): Reads up to a specified number of bytes from the input stream. The length of the returned array equals the number of bytes read from the stream. If len is zero, then no bytes are read and an empty byte array is returned. Otherwise, up to len bytes are read from the stream. Fewer than len bytes may be read if end of stream is encountered.

The new method will returns the specified number of bytes when the old one reads the requested number of bytes from the input stream into the given byte array with specified start position and len.

ReadNBytes.java
package com.dariawan.io;

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

public class ReadNBytes {

    public static void main(String[] args) throws IOException {
        var classLoader = ClassLoader.getSystemClassLoader();
        
        try (InputStream inputStream = classLoader.getResourceAsStream("test.txt")) {
            byte[] bytes1 = inputStream.readNBytes(5);  // new method
            System.out.println(new String(bytes1));
            
            byte[] bytes2 = new byte[50];
            var n = inputStream.readNBytes(bytes2, 0, 50);  // old method
            System.out.println(new String(bytes2));
            System.out.println(n);            
        }
    }
}
                    

This is test file... 15

the first readNBytes(5) will read 5 bytes from InputStream, the second readNBytes(bytes2, 0, 50) will read the next 50 bytes from InputStream (start with position 0). It'll only return 15 bytes, since it reads until end of the streams.

New Constructors for FileReader and FileWriter

java.io.FileReader added two new constructors that allow a Charset to be specified:

java.io.FileWriter added four new constructors that allow a Charset to be specified:

FileReaderWriterCharset.java
package com.dariawan.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileReaderWriterCharset {

    public static void main(String[] args) throws IOException {
        var classLoader = ClassLoader.getSystemClassLoader();
        var url = classLoader.getResource("test.txt");

        Path tempPath = Files.createTempFile("test", ".txt");
        File tempFile = tempPath.toFile();
        tempFile.deleteOnExit();

        Charset latinCharset = Charset.forName("ISO-8859-3");
        try (FileWriter fw = new FileWriter(tempFile, latinCharset)) {
            fw.write("The price is £100 or about €120\n");
            fw.write("You need to bring at least 150$");
        }
        
        try (FileReader fr = new FileReader(tempFile, latinCharset)) {
            new BufferedReader(fr).lines().forEach(System.out::println);
        }
    }
}
                    

The price is £100 or about ?120 You need to bring at least 150$