Creating mp4 file doesn't remove tmp files

Viewed 79

I'm trying to write an InputStream that is an mp4 that I get from calling an external SOAP service, when I do so, it always generates this tmp files for my chosen temporary directory(java.io.tmpdir) that aren't removable and stay after the writing is done.

Writing images that I also get from the SOAP service works normal without the permanent tmp on the directory. I'm using java 1.8 SpringBoot

tmp files

This is what I'm doing:


File targetFile = new File("D:/archive/video.mp4");
targetFile.getParentFile().mkdirs(); 
targetFile.setWritable(true);

InputStream inputStream = filesToWrite.getInputStream();
OutputStream outputStream = new FileOutputStream(targetFile);

                    try {

                        int byteRead;

                        while ((byteRead = inputStream.read()) != -1) {
                            outputStream.write(byteRead);
                        }

                    } catch (IOException e) {
                        logger.fatal("Error@ SaveFilesThread for guid:  " + guid, e);
                    }finally {
                        try {
                            inputStream.close();
                            outputStream.flush();
                            outputStream.close();

                        }catch (Exception e){
                            e.printStackTrace();
                        }

also tried:

byte data[] = IOUtils.toByteArray(inputStream);
Path file = Paths.get("video.mp4");
Files.write(file, data);

And from apache commons IO:

 FileUtils.copyInputStreamToFile(initialStream, targetFile);
1 Answers

When your code starts, the damage is already done. Your code is not the source of the temporary files (It's.. a ton of work for something that could be done so much simpler, though, see below), it's the framework that ends up handing you that filesToWrite variable.

It is somewhat likely that you can hook in at an earlier point and get the raw inputstream representing the socket or HTTP connection, and start saving the files straight from there. Alternatively, Perhaps filesToWrite has a way to get at the files themselves, in which case you can just move them into place instead of copying them over.

But, your code to do this is a mess, it has bad exception handling, and leaks memory, and is way too much code for a simple job, and is possibly 2000x to 10000x slower than needed depending on your harddisk (I'm not exaggerating, calling single-byte read() on unbuffered streams is thousands of times slower!)

// add `throws IOException` to your method signature.
// it saves files, it's supposed to throw IOException,
// 'doing I/O' is in the very definition of your method!

try (InputStream in = filesToWrite.getInputStream();
  OutputStream out = new FileOutputStream(targetFile)) {

    in.transferTo(out);
}

That's it. That solves all the problems - no leaks, no speed loss, tiny amount of code, fixes the deplorable error handling (which, here, is 'log something to the log, then print something to standard out, then potentially leak a bunch of resources, then don't tell the calling code anything went wrong and return exactly as if the copy operation succeeded).

Related