【问题标题】:Memory Efficient File/Image Upload in Java? [closed]Java中的内存高效文件/图像上传? [关闭]
【发布时间】:2013-08-29 14:36:12
【问题描述】:

我想将 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){ }

Here我读到有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))

哪个更好?

【问题讨论】:

    标签: java servlets grails grails-2.0


    【解决方案1】:

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

    【讨论】:

    • 我的备选方案 1 是否与此相同:commons.apache.org/proper/commons-fileupload/streaming.html ?有那么快吗?
    • @stephan1001 使用transferTo 应该始终是做你想做的最快的方法。 Commons-fileupload 缓冲内存中的小上传并将较大的上传到磁盘上的临时文件。如果文件已经在内存中缓冲,则调用transferTo 将转储缓冲区,或者如果可以重命名临时文件,或者如果不能,则从临时文件流式复制到目标。让框架使用其“内幕知识”为每个文件选择最有效的方法永远不会比自己选择一种方法并无条件地使用它慢。
    • 编码是我必须在这里处理的事情吗?如果是这样,我怎样才能确保传入的文件是 UTF-8 编码的?
    • @stephan1001 不,字符编码仅适用于文本数据,图像是纯二进制数据,transferTo 只是将上传的字节保存到文件中,而不管这些字节代表什么。
    • @stephan1001 不,字符编码仅适用于文本数据...
    【解决方案2】:

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

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

    【讨论】:

    • 你能放置commons-fileupload流的代码吗?当我做 file.inputStream 不是你的意思吗?我还更新了我的帖子是第二种选择更好吗?
    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 2020-03-10
    • 2012-09-27
    • 2012-07-20
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多