Java Try-with-resource在Map中存储输入流

Joh*_*y19 2 java memory-leaks inputstream try-with-resources

在我的API(Spring启动)中,我有一个端点,用户可以一次上传多个文件.端点将列表作为输入MultipartFile.

我希望不直接将此MultipartFile对象直接传递给服务,因此我遍历每个对象MultipartFile并创建一个存储文件名及其的简单映射InputStream.

像这样:

for (MultipartFile file : files) {       
      try (InputStream is = multipartFile.getInputStream()) {
        filesMap.put(file.getOriginalFilename(), is);
      }
    }
service.uploadFiles(filesMap)
Run Code Online (Sandbox Code Playgroud)

我对Java流和流关闭的理解非常有限.我认为一旦代码到达try块的末尾try-with-resources就会自动关闭InputStream.

在上面的代码中什么时候完全multipartFile.getInputStream()关闭?

我将流存储在地图中的事实会导致内存泄漏吗?

ar4*_*ers 6

在执行到try块的右括号后,流正好关闭.InputStream关闭后可以存储在任何地方.但请注意,关闭它后,您无法从此流中读取任何内容.

感谢评论

此外,请注意某些流具有特殊行为,close()并且始终取决于Stream实现.例如:

  • 如果你尝试从关闭阅读,FileInputStream你会得到 java.io.IOException: Stream Closed
  • 如果你试图从关闭中读取ByteArrayInputStream它就没关系,因为它的特殊close()实现:public void close() throws IOException {}

  • @ Johny19那个InputStream的类型是什么?根据你的说法,我敢打赌它是像ByteArrayInputStream这样的例子,其中close方法是空的(不需要直接关闭ByteArrayInputStream) (2认同)

And*_*lko 5

  1. 什么时候multipartFile.getInputStream()关闭?
try (InputStream is = multipartFile.getInputStream()) {
     filesMap.put(file.getOriginalFilename(), is);
} // <-- here
Run Code Online (Sandbox Code Playgroud)

try-with-resources语句确保在语句结束时关闭每个资源.


  1. 我将流存储在地图中的事实会导致内存泄漏吗?

不,你的收藏只是保持关闭InputStream,你将无法从他们那里读取(此外,你会得到IOException).