创建 mp4 文件不会删除 tmp 文件

问题描述

我正在尝试编写一个 InputStream,它是我通过调用外部 SOAP 服务获得的 mp4,当我这样做时,它总是为我选择的临时目录 (java.io.tmpdir) 生成这个 tmp 文件,这些文件不是'不可移动,写完后留下。

我也从 SOAP 服务获得的写入图像正常工作,目录上没有永久 tmp。我正在使用 java 1.8 SpringBoot

tmp files

这就是我正在做的:


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();
                        }

也尝试过:

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

来自 apache commons IO:

 FileUtils.copyInputStreamToFile(initialStream,targetFile);

解决方法

当您的代码启动时,损坏已经造成。您的代码不是临时文件的来源(它是.. 大量的工作可以完成如此​​简单的事情,但是,请参见下文),它是最终将 filesToWrite 变量交给您的框架。

您可能可以在较早的时间点挂钩并获取表示套接字或 HTTP 连接的原始输入流,然后直接从那里开始保存文件。或者,也许 filesToWrite 有办法自己获取文件,在这种情况下,您只需将它们移动到位,而不必复制它们。

但是,您执行此操作的代码一团糟,它具有糟糕的异常处理和内存泄漏,并且对于一个简单的工作来说代码太多,并且可能比您的硬盘慢 2000 到 10000 倍,具体取决于您的硬盘(我并不夸张,在无缓冲的流上调用单字节 read() 会慢数千倍!)

// 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);
}

就是这样。这解决了所有问题 - 没有泄漏,没有速度损失,少量代码,修复了令人遗憾的错误处理(这里是“将某些内容记录到日志中,然后将某些内容打印到标准输出中,然后可能会泄漏大量资源,然后不要告诉调用代码出了什么问题,直接返回,就像复制操作成功一样)。