我正在尝试通过从Java客户端到Tomcat中运行的servlet的Http输出流发送一些非常大的文件(> 200MB)。
我的协议当前将文件内容打包在byte[]
中,并放置一个Map<String, Object>
以及一些元数据(文件名等),每个部分都在“标准”键下({{1 }} - &gt; "FILENAME"
,"Foo"
- &gt; "CONTENTS"
,byte[]
- &gt; "USERID"
等。 1234
将写入URL连接输出流(Map
)。当文件内容很小(<25MB)时,这很有效,但是当文件大小非常大时,我遇到了Tomcat内存问题(urlConnection.getOutputStream()
)。
我想先发送元数据OutOfMemoryError
,然后发送文件内容,最后发送文件数据的校验和。接收器servlet然后可以从其输入流中读取元数据,然后读取字节直到整个文件完成,最后读取校验和。
在连接头中发送元数据会更好吗?如果是这样,怎么样?如果我首先向套接字发送元数据,然后是文件内容,那么是否有某种标准协议用于执行此操作?
答案 0 :(得分:2)
您几乎肯定希望使用multipart POST将数据发送到服务器。然后在服务器上,您可以使用commons-fileupload之类的内容来处理上传。
commons-fileupload的好处在于它了解服务器可能没有足够的内存来缓冲大文件,并且一旦超过一定大小就会自动将上传的数据流式传输到磁盘,这对避免{{{ 1}}类型问题。
否则你将不得不自己实施类似的东西。只要服务器可以1)解析上传并且2)将数据重定向到文件以便它不必在内存中缓冲整个请求,那么打包和发送数据的方式并没有太大的区别。立刻。如上所述,如果你使用commons-fileupload,这两个都是免费的,所以这绝对是我推荐的。
答案 1 :(得分:0)
我没有直接的答案,但您可以考虑使用FTP代替。 Apache Mina提供了FTPLets,实质上是响应FTP事件的servlet(有关详细信息,请参阅http://mina.apache.org/ftpserver/ftplet.html)。
这将允许您以任何格式推送数据,而无需接收端将整个数据容纳在内存中。
问候。