Extended MultipartEntity doesn't write out Streams correctly
I want to implement a ProgressDialog in my AndroidHttpClient. I found a simple implementatio开发者_JAVA技巧n here CountingMultipartEntity.
Additional I added the content length support. I override the methodaddPart
.
The FileBody upload works almost fine. When the upload contains one file it works perfect, but when there are two files the second file is only uploaded partial.
The InputStreamBody works but only when I don't count the length of the InputStream. So I have to reset it, but how?
Here my overriding addPart
:
@Override
public void addPart(String name, ContentBody cb) {
if (cb instanceof FileBody) {
this.contentLength += ((FileBody) cb).getFile().length();
} else if (cb instanceof InputStreamBody) {
try {
CountingInputStream in =
new CountingInputStream(((InputStreamBody) cb).getInputStream());
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
this.contentLength += in.getBytesRead();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
super.addPart(name, cb);
}
The CountingInputStream is a simple extension of the InputStream:
public class CountingInputStream extends InputStream {
private InputStream source;
private long bytesRead = 0;
public CountingInputStream(InputStream source) {
this.source = source;
}
public int read() throws IOException {
int value = source.read();
bytesRead++;
return value;
}
public long getBytesRead() {
return bytesRead;
}
}
The counting works almost, there are only 2 bytes, which shouldn't be there. But that is so important.
First I thought the stream must be reseted. The reset called after in.getReadedBytes();
leads into an IOException.
Thanks for any advices.
I found my mistake. I had overwritten the method getContentLength()
, which is important for the transmission, after removing my own version the file transmission works fine.
To get the size of an InputStream I used the class above but edited the method getBytesRead()
, because the ObjectInputStream causes a StreamCorruptedException:
public long getBytesRead() {
try {
while (read() != -1)
;
} catch (IOException e) {
e.printStackTrace();
}
return bytesRead;
}
To get the content length, you can take the given method getContentLength()
if there aren't any streams.
Otherwise you have to implement your own content length calculation. The method addPart(String name, ContentBody cb)
above provides an approach. More details about the content length calculation you can get from the classes MultiPartyEntity and HttpMultipart.
精彩评论