ash*_*wla 14 java http out-of-memory
我试图将一个大的视频/图像文件从本地文件系统发布到一个http路径,但一段时间后我遇到内存不足错误...
这是代码
public boolean publishFile(URI publishTo, String localPath) throws Exception {
InputStream istream = null;
OutputStream ostream = null;
boolean isPublishSuccess = false;
URL url = makeURL(publishTo.getHost(), this.port, publishTo.getPath());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if (conn != null) {
try {
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("PUT");
istream = new FileInputStream(localPath);
ostream = conn.getOutputStream();
int n;
byte[] buf = new byte[4096];
while ((n = istream.read(buf, 0, buf.length)) > 0) {
ostream.write(buf, 0, n); //<--- ERROR happens on this line.......???
}
int rc = conn.getResponseCode();
if (rc == 201) {
isPublishSuccess = true;
}
} catch (Exception ex) {
log.error(ex);
} finally {
if (ostream != null) {
ostream.close();
}
if (istream != null) {
istream.close();
}
}
}
return isPublishSuccess;
}
Run Code Online (Sandbox Code Playgroud)
HEre是我得到的错误......
Exception in thread "Thread-8773" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:61)
at com.test.HTTPClient.publishFile(HTTPClient.java:110)
at com.test.HttpFileTransport.put(HttpFileTransport.java:97)
Run Code Online (Sandbox Code Playgroud)
kdg*_*ory 15
所述HttpUrlConnection被缓冲的数据,以便它可以设置Content-Length(每头HTTP规范).
如果目标服务器支持,则另一种方法是使用" 分块 "传输.这将一次只缓冲一小部分数据.但是,并非所有服务都支持它(例如,Amazon S3不支持).
另一个替代方案(并且更好的方法)是使用Jakarta HttpClient.您可以在文件的请求中设置"实体",连接代码将适当地设置请求标头.
编辑:nos评论OP可以调用HttpURLConnection.setFixedLengthStreamingMode(long length).我没有意识到这种方法; 它是在1.5中添加的,从那以后我没有使用过这个类.
但是,我仍然建议使用Jakarta HttpClient,原因很简单,它减少了OP必须维护的代码量.代码是样板,但仍有可能出错:
finally区块中的连接,并再次祝贺.除了任何一个close()调用可以抛出IOException,保持另一个执行.并且该方法作为一个整体抛出Exception,因此编译器不会帮助捕获类似的错误.即使OP完全编写了这段代码,并将其重构为类似于Jakarta Commons IO中的方法,他/她也不应该这样做.此代码已由其他人编写和测试.我知道重写它是浪费我的时间,并怀疑它也浪费了OP的时间.
conn.setFixedLengthStreamingMode((int) new File(localpath).length());
Run Code Online (Sandbox Code Playgroud)
对于缓冲,您可以将流覆盖到BufferedOutputStream和BufferedInputStream中
可以在此处找到分块上传的好例子:gdata-java-client
| 归档时间: |
|
| 查看次数: |
14301 次 |
| 最近记录: |