简体   繁体   English

使用InputStreams上传图像=内存不足错误

[英]Uploading Image using InputStreams = Out Of Memory error

I am trying to upload an image but I am getting some out of memory errors if the image file is over ~2 megs on an Android device. 我正在尝试上传图像,但是如果图像文件在Android设备上超过〜2兆,则会遇到内存不足错误。

File file = new File(<my image file>);
FileInputStream fis = new FileInputStream(file);
HttpClient client = new HttpClient(); 
PutMethod method = new PutMethod(myUrl); 
RequestEntity requestEntity = new InputStreamRequestEntity(fis);
method.setRequestEntity(requestEntity); 
client.executeMethod(method); 

The out of memory error happens on the executeMethod line. 内存不足错误发生在executeMethod行上。 How can I change this to read the stream as it goes along instead of reading the entire stream into memory and causing a crash? 我如何更改它以在流进行时读取流,而不是将整个流读入内存并导致崩溃?

Sample of hte DDMS output: DDMS输出的样本:

07-27 10:46:24.334: DEBUG/dalvikvm(26576): GC freed 6787 objects / 522592 bytes in 119ms
07-27 10:46:24.374: DEBUG/dalvikvm(26576): GC freed 1738 objects / 196752 bytes in 33ms
07-27 10:46:24.374: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 5.184MB for 253968-byte allocation
07-27 10:46:24.414: DEBUG/dalvikvm(26576): GC freed 0 objects / 0 bytes in 45ms
07-27 10:46:24.464: DEBUG/dalvikvm(26576): GC freed 3 objects / 122992 bytes in 48ms
07-27 10:46:24.474: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 5.558MB for 516112-byte allocation
07-27 10:46:24.524: DEBUG/dalvikvm(26576): GC freed 0 objects / 0 bytes in 57ms
07-27 10:46:24.574: DEBUG/dalvikvm(26576): GC freed 3 objects / 254056 bytes in 46ms
07-27 10:46:24.754: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 6.308MB for 1040400-byte allocation
07-27 10:46:24.824: DEBUG/dalvikvm(26576): GC freed 3 objects / 516168 bytes in 63ms
07-27 10:46:24.894: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 7.808MB for 2088976-byte allocation
07-27 10:46:24.994: DEBUG/dalvikvm(26576): GC freed 0 objects / 0 bytes in 101ms
07-27 10:46:25.034: DEBUG/dalvikvm(26576): GC freed 3 objects / 1040456 bytes in 34ms
07-27 10:46:25.084: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 10.808MB for 4186128-byte allocation
07-27 10:46:25.154: DEBUG/dalvikvm(26576): GC freed 0 objects / 0 bytes in 63ms
07-27 10:46:25.434: DEBUG/dalvikvm(26576): GC freed 3 objects / 2089032 bytes in 58ms
07-27 10:46:25.714: INFO/dalvikvm-heap(26576): Grow heap (frag case) to 16.808MB for 8380432-byte allocation
07-27 10:46:25.784: DEBUG/dalvikvm(26576): GC freed 0 objects / 0 bytes in 70ms
07-27 10:46:26.204: DEBUG/dalvikvm(26576): GC freed 3 objects / 4186184 bytes in 65ms
07-27 10:46:26.204: INFO/dalvikvm-heap(26576): Forcing collection of SoftReferences for 16769040-byte allocation

Constructing InputStreamRequestEntity without a length causes it to buffer the data locally so it can determine a length. 构造没有长度的InputStreamRequestEntity会导致它在本地缓冲数据,以便可以确定长度。 Since you have it as a file, use FileRequestEntity instead as it will determine the size from the file. 由于您将其作为文件,因此请使用FileRequestEntity ,因为它将确定文件的大小。

The InputStreamRequestEntity class indicates that you're still using the old HttpClient 3.x . InputStreamRequestEntity类表明您仍在使用旧的HttpClient3.x

So you have 3 options: 因此,您有3个选择:

  1. Upgrade to HttpClient 4.0 which advertises itself with: 升级到HttpClient 4.0 ,该服务器通过以下方式进行宣传:

    Request output streams to avoid buffering any content body by streaming directly to the socket to the server. 请求输出流,以避免通过直接流到服务器的套接字来缓冲任何内容主体。

    Not sure though if upgrading is possible on Android since it seems to be builtin. 由于它是内置的,因此不确定是否可以在Android上进行升级。

  2. Follow the request entity streaming advice in HttpClient 3.x performance guide . 请遵循HttpClient 3.x 性能指南中的请求实体流建议。

    Request streaming : The main difficulty encountered when streaming request bodies is that some entity enclosing methods need to be retried due to an authentication failure or an I/O failure. 请求流式传输 :流式传输请求主体时遇到的主要困难是由于身份验证失败或I / O失败而需要重试某些实体封装方法。 Obviously non-buffered entities cannot be reread and resubmitted. 显然,非缓冲实体无法重新读取和重新提交。 The recommended approach is to create a custom RequestEntity capable of reconstructing the underlying input stream. 推荐的方法是创建一个自定义RequestEntity ,该实体能够重建基础输入流。

    (snip, code example) (代码段示例)

  3. Grab "plain vanilla" java.net.URLConnection , cast it to HttpURLConnection and set the streaming mode. 抓住“普通香草” java.net.URLConnection ,将其转换为HttpURLConnection并设置流模式。 Eg 例如

     ((HttpURLConnection) connection).setChunkedStreamingMode(1024); 

    which will send the request body in chunks of 1KB. 它将以1KB的块发送请求正文。 More hints here . 这里有更多提示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM