Sophie
Sophie

Reputation: 1600

How to monitor file upload progress?

I need to upload a file to server and monitor it's progress. i need to get a notification how many bytes are sent each time.

For example in case of download i have:

HttpURLConnection  connection = (HttpURLConnection) m_url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
while ((currentBytes  = stream.read(byteBuffer)) > 0) {                    
    totalBytes+=currentBytes;
    //calculate something...
}

Now i need to do the same for upload. but if use

OutputStreamWriter stream = new OutputStreamWriter(connection.getOutputStream());
stream.write(str);
stream.flush();

than i can't get any progres notification, about how many bytes are sent (it looks like automic action).

Any suggestions?

Thanks

Upvotes: 4

Views: 3254

Answers (6)

user207421
user207421

Reputation: 311023

Just set chunked transfer mode and monitor your own writes to the output stream.

If you don't use chunked or fixed-length transfer mode, your writes are all written to a ByteArrayOutputStream before being written to the network, so that Java can set the Content-Length header correctly. This is what made you think it is non-blocking. It isn't.

Upvotes: 5

Sophie
Sophie

Reputation: 1600

I have used ChannelSocket object. This object allows to do blocking read and write when accessing the server. So i emulated HTTP using this socket and each write request was blocked untill it was done. This way i could follow the actual progress of write transaction.

Upvotes: 4

helios
helios

Reputation: 13841

A different approach is polling the server asking how much of the data is uploaded. Maybe using an id or something.

POST -> /uploadfile

  • id
  • file

POST -> /queryuploadstate (Returns the partial size)

  • id

Of course it needs the servlets to be connected and doesn't allow clustering...

Upvotes: 0

MirroredFate
MirroredFate

Reputation: 12835

It would be similar to the way your download works.

OutputStream stream = connection.getOutputStream();
for(byte b: str.getBytes()) {                    
    totalBytes+=1;
    stream.write(b);
    if(totalBytes%50 == 0)
        stream.flush(); //bytes will be sent in chunks of 50
    //calculate something...
}
stream.flush();

Something like that.

Upvotes: 0

Atreys
Atreys

Reputation: 3761

If you want to count the bytes you're uploading, write the objects as byte arrays to the output stream itself, like you are doing with the input stream.

Upvotes: 1

user7094
user7094

Reputation:

What I have done in similar situations is create a subclass of FilterOutputStream which overrides the write(...) methods and can then notify your code of any written bytes.

Upvotes: 2

Related Questions