Handle temporary file in try with resources

link picture link · Dec 2, 2015 · Viewed 8.3k times · Source

For my application, I have to write a method that takes an InputStream as argument, writes the content to a temporary file, performs some operations and finally deletes the temporary.

This is what I have so far:

public void myMethod(InputStream in, String name) {
    //...
    Path path = Paths.get("./tmp/benchmarks/" + name + ".zip")

    try {
        Files.copy(in, path);
        //operations...
    } catch (IOException e) {
        //error handling for copy...
    } finally {
        try {
            Files.delete(path));
       } catch (IOException e) {
           //error handling for delete...
       }
    }
    //...
}

It does the job, but it also looks really ugly. I was wondering if there was some way to use try-with-resources to handle this more gracefully. Is it possible somehow?

UPDATE: I wrote an on-the-fly solution in ten minutes. It looks like this:

public class TemporaryFileHandler implements AutoCloseable {

    private File file;

    public TemporaryFileHandler(final InputStream in, final Path path) throws IOException {
        Files.copy(in, path);
        this.file = new File(path.toString());
    }

    public File getFile() { return file; }

    @Override
    public void close() throws IOException {
        Files.delete(file.toPath());
    }
}

I'm sure it's not the best, but it does the job for now. If anyone has suggestions on how to improve this in any way, suggestions are more than welcome.

Answer

zapl picture zapl · Dec 2, 2015

I think with a little helper / wrapper like

public class AutoDeletingTempFile implements AutoCloseable {

    private final Path file;

    public AutoDeletingTempFile() throws IOException {
        file = Files.createTempFile(null, null);
    }

    public Path getFile() {
        return file;
    }

    @Override
    public void close() throws IOException {
        Files.deleteIfExists(file);
    }
}

which gets closed and deletes the file it wraps you get a nice and short syntax:

public void myMethod(InputStream in, String name) {
    try (AutoDeletingTempFile wrapper = new AutoDeletingTempFile()) {
        //Files.copy(in, wrapper.getFile());
        //operations...
    } catch (IOException e) {
        //error handling for copy...
        // + temp file creation
    }
}

or a neat little Closable via lambdas

public void myMethod(InputStream in, Path existingFile, String name) {
    try (Closeable closable = () -> Files.deleteIfExists(existingFile)) {
        // ...
    } catch (IOException e) {
        // 
    }
}