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

Java Try-with-resource storing input stream in Map

在我的 API(Spring 引导)中,我有一个端点,用户可以在其中一次上传多个文件。端点将 MultipartFile.

的列表作为输入

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

像这样:

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

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

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

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

流在执行到 try 块的右括号后立即关闭。 关闭后将 InputStream 存储在任何地方都可以。 但请注意,关闭后您无法从该流中读取任何内容

感谢评论

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

  • 如果你尝试从关闭的 FileInputStream 中读取你会得到 java.io.IOException: Stream Closed
  • 如果你尝试从关闭的 ByteArrayInputStream 读取它会没问题,因为它是特殊的 close() 实现:public void close() throws IOException {}
  1. When does exactly the multipartFile.getInputStream() gets closed?
try (InputStream is = multipartFile.getInputStream()) {
     filesMap.put(file.getOriginalFilename(), is);
} // <-- here

The try-with-resources statement ensures that each resource is closed at the end of the statement.


  1. The fact that I'm storing the stream in a map will that cause a memory leak?

不,您的 collection 只是保持关闭 InputStreams,您将无法读取它们(此外,您将获得 IOException)。