Java 9 - Input Output Stream Changes

[Updated: Dec 15, 2017, Created: Dec 15, 2017]

Followings are quick java.io changes in Java 9.

Object DeSerialization Filter

Following new method has been added to ObjectInputStream:

public final void setObjectInputFilter(ObjectInputFilter filter)

This method allows us to set a serialization filter. Following is a quick snippet of the new functional interface ObjectInputFilter:

package java.io;
 ....
@FunctionalInterface
public interface ObjectInputFilter {
    Status checkInput(FilterInfo filterInfo);

     /**
        * FilterInfo provides access to information about the current object being deserialized.
        */
    interface FilterInfo {
        Class<?> serialClass(); //The class of an object being deserialized.
        long arrayLength();//The number of array elements when deserializing an array of the class.
        long depth();//The current depth of the object graph.
        long references();// The current number of object references.
        long streamBytes();//The current number of bytes consumed.
    }

    enum Status {
        UNDECIDED,//not allowed and not rejected.
        ALLOWED,
        REJECTED;
    }
   ......
   ......
}

Example

Following example disallows the deserialization of any class which extends JComponent:

public class ObjectInputFilterExample {

    public static void main(String[] args) throws Exception {
        objectOutputInputTest(new TestClass());
        objectOutputInputTest(new TestClass2());
    }

    private static void objectOutputInputTest(Object objectToSerialize) throws Exception {
        //serializing object
        Path path = Files.createTempFile("test-class-file", "");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(
                new FileOutputStream(path.toFile()));
        try (objectOutputStream) {
            objectOutputStream.writeObject(objectToSerialize);
        }

        //deserializing object
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(path.toFile()));
        objectInputStream.setObjectInputFilter(createObjectFilter());//setting filter
        try (objectInputStream) {
            Object o = objectInputStream.readObject();
            System.out.println("Object deserialized: "+o);
        }
    }

    private static ObjectInputFilter createObjectFilter() {
        return filterInfo -> {
            Class<?> theClass = filterInfo.serialClass();
            if (JComponent.class.isAssignableFrom(theClass)) {
                System.err.println("JComponent class is not allowed for serialization: " +
                        theClass.getSimpleName());
                return ObjectInputFilter.Status.REJECTED;
            }
            System.out.println("Allowed: " + theClass.getSimpleName());
            return ObjectInputFilter.Status.ALLOWED;
        };
    }

    public static class TestClass implements Serializable {
    }

    public static class TestClass2 extends JComponent implements Serializable {
    }
}

Output

Allowed: TestClass
Object deserialized: com.logicbig.example.ObjectInputFilterExample$TestClass@4566e5bd
JComponent class is not allowed for serialization: TestClass2
Exception in thread "main" java.io.InvalidClassException: filter status: REJECTED
	at java.base/java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1278)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1891)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1764)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2055)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1586)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:423)
	at com.logicbig.example.ObjectInputFilterExample.objectOutputInputTest(ObjectInputFilterExample.java:27)
	at com.logicbig.example.ObjectInputFilterExample.main(ObjectInputFilterExample.java:13)

Transferring data from an InputStream to OutputStream

Following new method has been added to InputStream class:

public long transferTo(OutputStream out) throws IOException

Example:

public class InputStreamTransferTo {
  public static void main(String[] args) throws IOException {
      InputStream inputStream = getInputStream();
      Path path = Files.createTempFile("test-file", ".txt");
      OutputStream outputStream = new FileOutputStream(path.toFile());
      try (inputStream; outputStream) {
          inputStream.transferTo(outputStream);
      }
     Files.lines(path)
          .forEach(System.out::println);
  }

  public static InputStream getInputStream() {
      return new ByteArrayInputStream("test string".getBytes());
  }
}
test string

Reading all bytes from an InputStream

Following new method has also been added to InputStream class:

public byte[] readAllBytes() throws IOException

Example

public class InputStreamReadAllBytes {
  public static void main(String[] args) throws IOException {
      try (InputStream inputStream = getInputStream()) {
          byte[] bytes = inputStream.readAllBytes();
          System.out.println(new String(bytes));
      }
  }

  public static InputStream getInputStream() {
      return new ByteArrayInputStream("test string".getBytes());
  }
}
test string

Reading N number of bytes from an InputStream

Following new method has also been added to InputStream class:

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

Example

public class InputStreamReadNBytes {
  public static void main(String[] args) throws IOException {
      try (InputStream inputStream = getInputStream()) {
          byte[] bytesToRead = new byte[4];
          inputStream.readNBytes(bytesToRead, 0, bytesToRead.length);
          System.out.println(new String(bytesToRead));
      }
  }

  public static InputStream getInputStream() {
      return new ByteArrayInputStream("test string".getBytes());
  }
}
test

Example Project

Dependencies and Technologies Used :

  • JDK 9
  • Maven 3.3.9

Java 9 IO Changes Examples Select All Download
  • java-9-io-changes
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also