How to properly pass InputStream to another constructor? (Java)

AgentM :

In the code below I try to access my other constructor that takes a InputStream... However I need to somehow close this stream to avoid resource leaks. If I try to put a try catch around, it will complain that the constructor call isn't the first statement. Is there any way to pass this InputStream without any potential risks?

public Input(File source) throws FileNotFoundException {
    this(new FileInputStream(source));
}
flakes :

You'll want to make this class implement AutoClosable and make sure you use it within a try-with-resource:

public class Input extends SomeClass implements AutoCloseable {
    public Input(File source) throws FileNotFoundException {
        this(new FileInputStream(source));
    }
    @Override 
    public void close() {
        someMethodThatClosesInnerResource();
    }
}

You can then use the object like this:

try (Input input = new Input(source)) {
    ...
}

If you're concerned that the super constructor will throw an exception, then you might want to add a builder method to protect against early exceptions:

public class Input extends SomeClass implements AutoCloseable {
    public static Input createInput(File source) throws Exception {
        FileInputStream inputstream = new FileInputStream(source);
        try {
            return new Input(inputstream);
        } catch (Exception e) {
            inputstream.close();
            throw e;
        }
    }
    private Input(FileInputStream source)  {
        this(source);
    }
    @Override 
    public void close() {
        someMethodThatClosesInnerResource();
    }
}

You should then still use this as a try-with-resource:

try (Input input = Input.createInput(source)) {
    ...
}

Notice in the builder method you have to protect against all exceptions... this is not great practice as now you have to make the method throw a general exception... or use a utility to throw silently. You can avoid this issues by just not having the constructor create the FileInputStream. Instead just inject the FileInputStream into your class and create it in the try-with-resource as well. This will safely allow both objects to be closed in the event of a ctor exception:

try (
    FileInputStream stream = new FileInputStream(source);
    Input input = new Input(stream)
) {
    ...
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=151745&siteId=1