In this tutorial we will go through new methods of java.io package added in Java 11.
Null InputStream/OutputStream/Reader/Writer
There are situations where we use methods that require InputStream/OutputStream/Reader/Writer parameter and we want to process the parameter transparently even it represents a null input/output stream.
Before Java 11 it was not possible to initialize a stream with null (i.e. creating a stream with disabled input/output) as they throw NullPointerException if null is passed to the corresponding constructor (e.g new FileInputStream(null), new ByteArrayInputStream(null)).
Following new methods have been added which return streams that represent disabled input/output. They read nothing or discard all writes.
java.io.InputStream class:
public static InputStream nullInputStream()
java.io.OutputStream class:
public static OutputStream nullOutputStream()
java.io.Reader class:
public static Reader nullReader()
java.io.Writer class:
public static Writer nullWriter()
All returned streams are initially open.
Calling read()/skip()/transferTo() methods on the returned input streams behave as end of the stream has reached.
Calling write()/append()/flush() methods on the returned output streams do nothing.
After a stream has been closed, calling read/write methods will throw IOException.
Examples
Reading:
public class NullReaderExample {
public static void main(String[] args) throws IOException {
Reader reader1 = new StringReader("test string data");
Reader reader2 = Reader.nullReader();//new method
Reader reader3 = new CharArrayReader(new char[]{'a', 'b', 'c'});
printData(List.of(reader1, reader2, reader3));
reader1.close();
reader2.close();
reader3.close();
}
public static void printData(List<Reader> readers) {
readers.stream()
.map(BufferedReader::new)
.map(BufferedReader::lines)
.forEach(stream -> stream.forEach(System.out::println));
}
} test string data abc
Writing:
public class NullWriterExample {
public static void main(String[] args) throws IOException {
Writer writer1 = new StringWriter();
Writer writer2 = Writer.nullWriter();//new method
Writer writer3 = new CharArrayWriter();
List<Writer> list = List.of(writer1, writer2, writer3);
writeData(list);
//just check the buf content via toString
list.forEach(writer -> {
//toString prints underlying data buffer -
//nullWriter has no buffer and does not override toString
System.out.printf("writer type: %s, toString: %s%n",
writer.getClass().getSimpleName(),
writer.toString());
});
}
public static void writeData(List<Writer> writers) throws IOException {
for (Writer writer : writers) {
writer.write(Integer.toString(ThreadLocalRandom.current().nextInt()));
writer.close();
}
}
} writer type: StringWriter, toString: -1912418667 writer type: , toString: java.io.Writer$1@1b0375b3 writer type: CharArrayWriter, toString: -490192658
Before Java 11 same result could be achieved by creating a wrapper class which could ignore all reads and writes. Also see JDK-4358774 and JDK-8196298.
Returning specified bytes with InputStream.readNBytes(int)
public byte[] readNBytes(int len) throws IOException
This method reads up to a specified number of bytes from the input stream.
Example
public class InputStreamReadNBytesExample {
public static void main(String[] args) throws IOException {
InputStream stream = new ByteArrayInputStream("test data".getBytes());
byte[] bytes = stream.readNBytes(4);//new method
System.out.println(new String(bytes));
stream.close();
}
} test
The old readNBytes() method:
public int readNBytes(byte[] b, int off, int len) throws IOException
The difference between above old method and the new method is that the old method reads the requested number of bytes from the input stream into the given byte array, whereas the new method returns the specified number of bytes
See also JDK-8139206.
FileReader/FilterWriter new constructors
FileReader and FileWriter have new constructors with additional Charset parameter.
FileReader class:
public FileReader(String fileName, Charset charset) throws IOException
public FileReader(File file, Charset charset) throws IOException
FileWriter class
public FileWriter(String fileName, Charset charset) throws IOException
public FileWriter(String fileName, Charset charset, boolean append) throws IOException
public FileWriter(File file, Charset charset) throws IOException
public FileWriter(File file, Charset charset, boolean append) throws IOException
Example
public class FileReaderWriterCharsetExample {
public static void main(String[] args) throws IOException {
Path path = Files.createTempFile("test", ".txt");
File targetFile = path.toFile();
targetFile.deleteOnExit();
Charset latinCharset = Charset.forName("ISO-8859-3");
//FileWriter new constructor
FileWriter fw = new FileWriter(targetFile, latinCharset);
fw.write("test filum");
fw.close();;
//FileReader new constructor
FileReader fr = new FileReader(targetFile, latinCharset);
new BufferedReader(fr).lines().forEach(System.out::println);
fr.close();
}
} test filum
Example ProjectDependencies and Technologies Used: |