【发布时间】:2014-10-17 03:54:01
【问题描述】:
我正在尝试使用 HttpPost 获取实际文件上传的进度。到目前为止,我有一个稳定的解决方案(我在 SO 中找到),但在上传大文件后我意识到它只计算写入输出缓冲区的字节而不是传输后的进度。我想以某种方式获得实际“帖子”的进展。有人可以解释我如何使用我到目前为止努力工作的成果来实现这一目标吗?我在网上找到的大多数解决方案都只计算写入输出缓冲区的字节数(这对于小文件来说已经足够了,但在传输大文件时就不行了)。
public static String postFile(final Context context, String fileName) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://my.url/");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
final File file = new File(fileName);
final long totalSize = file.length();
FileBody fb = new FileBody(file);
builder.addPart("uploaded_file", new FileBody(new File(fileName)));
final HttpEntity yourEntity = builder.build();
int progressPercent = 0;
class ProgressiveEntity implements HttpEntity {
@Override
public void consumeContent() throws IOException {
yourEntity.consumeContent();
}
@Override
public InputStream getContent() throws IOException,
IllegalStateException {
return yourEntity.getContent();
}
@Override
public Header getContentEncoding() {
return yourEntity.getContentEncoding();
}
@Override
public long getContentLength() {
return yourEntity.getContentLength();
}
@Override
public Header getContentType() {
return yourEntity.getContentType();
}
@Override
public boolean isChunked() {
return yourEntity.isChunked();
}
@Override
public boolean isRepeatable() {
return yourEntity.isRepeatable();
}
@Override
public boolean isStreaming() {
return yourEntity.isStreaming();
} // CONSIDER put a _real_ delegator into here!
@Override
public void writeTo(OutputStream outstream) throws IOException {
class ProxyOutputStream extends FilterOutputStream {
public ProxyOutputStream(OutputStream proxy) {
super(proxy);
}
public void write(int idx) throws IOException {
out.write(idx);
}
public void write(byte[] bts) throws IOException {
out.write(bts);
}
public void write(byte[] bts, int st, int end) throws IOException {
out.write(bts, st, end);
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
} // CONSIDER import this class (and risk more Jar File Hell)
class ProgressiveOutputStream extends ProxyOutputStream {
long totalSent;
public ProgressiveOutputStream(OutputStream proxy) {
super(proxy);
totalSent = 0;
}
public void write(byte[] bts, int st, int end) throws IOException {
// end is the amount being sent this time
// st is always zero and end=bts.length()
totalSent += end;
int progress = (int) ((totalSent / (float) totalSize) * 100);
out.write(bts, st, end);
}
}
yourEntity.writeTo(new ProgressiveOutputStream(outstream));
}
};
ProgressiveEntity myEntity = new ProgressiveEntity();
post.setEntity(myEntity);
//Output to buffer is complete at this point!
HttpResponse response = client.execute(post);
String jsonResponseStr = getContent(response);
Log.d("MYTAG",jsonResponseStr);
return jsonResponseStr;
}
在远程服务器上的接收脚本中,我只是回显一个字符串,以便我可以立即发送响应(根本没有文件/数据库处理),而来自服务器的响应仍然需要很长时间。我坚信此时传输发生在写入缓冲区完成后。
【问题讨论】:
-
使用 publishProgress();检查this
-
@ashutiwari4 除非您使用我不认为我使用的任何方法的 setfixedlengthstreamingmode 选项,否则该答案还计算写入缓冲区进度。如果可能的话,我想避免重写我所拥有的一切。
-
NOT the post transfer progress.。什么是转后进度? -
@greenapps 当您写入缓冲区时,POST 并未真正开始。写入缓冲区完成后,开始发送到远程 url。我想跟踪 POST 的进度
-
所以你说我可以将一个 5 MB 的文件写入输出流,然后实际传输将开始?好吧,我很难相信。
标签: java android http-post multipartentity