最近在安卓上用到这个Apache的http请求工具包,需要做一个上传文件进度的功能,各种搜也没找到这个实现获取上传进度的资料,也没办法换安卓提供原生的http请求和其他工具包,不得已自己下载源码研究了一下。
关键的类是FilePart,在上传的时候是需要把文件丢到这个part里面的,在请求发送的时候每个part都会掉用其中的sendData去发送流数据,那么要获取发送的流大小就需要在这里监听了,下面是我写了一个类,继承FilePart并重写了sendData方法。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.util.EncodingUtil;
public class CustomFilePart extends FilePart {
public CustomFilePart(String filename, File file) throws FileNotFoundException {
super(filename, file);
}
protected void sendDispositionHeader(OutputStream out) throws IOException {
super.sendDispositionHeader(out);
//这里是处理文件名乱码问题,跟本文主题无关,有同样问题的可使用
String filename = getSource().getFileName();
if (filename != null) {
out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getBytes(filename, "utf-8"));
out.write(QUOTE_BYTES);
}
}
@Override
protected void sendData(OutputStream out) throws IOException {
// TODO Auto-generated method stub
// super.sendData(out);
long countSize = lengthOfData();
if (countSize == 0) {
// this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
// cause an infinite loop when reading.
return;
}
byte[] tmp = new byte[4096];
InputStream instream = super.getSource().createInputStream();
try {
int len, currentLength = 0;
while ((len = instream.read(tmp)) >= 0) {
out.write(tmp, 0, len);
//将每次传输的流大小传给接口(只在这里增加了监听逻辑,a其余代码都是sendDate源码中直接复制过来的)
if (sendDataProgress != null) {
currentLength += len;
sendDataProgress.progress(currentLength, (int) countSize);
}
}
} finally {
// we're done with the stream, close it
instream.close();
}
}
private SendDataProgress sendDataProgress;
public void setSendDataProgress(SendDataProgress sendDataProgress) {
this.sendDataProgress = sendDataProgress;
}
//监听接口
public interface SendDataProgress {
void progress(int length, int countSize);
}
}