2

我想将 2MB - 10MB 的图像上传到我的服务器并将它们直接保存到硬盘。目标是尽可能多地节省 JVM 的堆内存,因为如果用户同时上传,我的系统不应该崩溃。

这就是我目前的做法。当带有上传的请求进入我的控制器时,我会:

CommonsMultipartFile file = (CommonsMultipartFile) request.getFile('image')
InputStream inputStream = file.inputStream
byte [] byteFile = inputStream.getBytes()

try{
  def fullPath = // some image path and file name
  def newFile = new FileOutputStream(fullPath)
  newFile.write(byteFile)
  newFile.close()
}
catch(IOException e){ }

在这里我读到有 ImageIO 和 java.awt.Toolkit,其中 Toolkit 应该是最快的存储文件。

如何改进我的上传以使用尽可能少的堆并尽可能快地上传?

备选方案 1:

一种替代方法可能是:

CommonsMultipartFile file = (CommonsMultipartFile) request.getFile('image')
def fullPath = // some image path and file name
file.transferTo(new File(fullPath))

哪一个更好?

4

2 回答 2

2

您当前的代码接收包含文件内容的输入流,然后将该流的全部内容缓冲在 a 中,byte[]然后再将其写入磁盘上的文件。您的“替代 1”流直接从输入流到磁盘上的文件,因此内存效率更高,并且至少与您当前的缓冲方法一样快(可能更快,因为沿途收集的垃圾更少)。

于 2013-08-29T15:34:59.610 回答
0

如果您使用 commons-fileupload 库并在流模式下使用它(此处的文档),您将永远不必在内存中保存比您想要的更多的传入文件。当请求来自客户端并且您遍历每个项目时,您会为每个表单字段或上传文件获得一个 InputStream,并且可以对该 InputStream 执行任何您想要的操作,例如将其写入文件(包括抛出异常)如果用户尝试上传 2GB 文件,而您的限制为 20MB 或其他)。

使用 commons-fleupload 的流 API 的唯一缺点是处理常规表单字段也必须通过 InputStream 完成,但通过调用 lib 的Streams.asString().

于 2013-08-29T15:01:12.973 回答