Question

i got a java method which returns the response of the website in a string. Now i want to add the possibility to track the progress of this request. I know i can calculate it via (contenLength/readBytes) *100. But i am not sure how to retrieve this information properly and update the progress everytime it changes. My current method looks like this:

public String executePost(URL url) {
    StringBuffer sb = new StringBuffer();
            int readBytes = 0;
            int contentLength = 0;
            int progress = 0;
    try {
        String newString = url.toString().replace(" ", "%20");
        URL newURL = new URL(newString);
        URLConnection conn = newURL.openConnection();
        conn.setDoOutput(true);
                    contentLength = conn.contentLength();
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                conn.getInputStream()));
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
                            readBytes += line.getBytes("ISO-8859-2").length + 2;
                            progress = (readBytes/contentLength)*100;
                            System.out.println(progress);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}
Was it helpful?

Solution

You can create an InputStream tracking the progress, e.g.

public class CountingInputStream extends FilterInputStream {
  long count;

  protected CountingInputStream(InputStream in)
  {
    super(in);
  }
  public long getCount()
  {
    return count;
  }
  @Override
  public int read() throws IOException
  {
    final int read = super.read();
    if(read>=0) count++;
    return read;
  }
  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    final int read = super.read(b, off, len);
    if(read>0) count+=read;
    return read;
  }
  @Override
  public long skip(long n) throws IOException {
    final long skipped = super.skip(n);
    if(skipped>0) count+=skipped;
    return skipped;
  }
}

Then change the line

BufferedReader rd = new BufferedReader(new InputStreamReader(
            conn.getInputStream()));

to

CountingInputStream counting = new CountingInputStream(conn.getInputStream());
BufferedReader rd = new BufferedReader(new InputStreamReader(counting));

then you can proceed as before and query the acual count via counting.getCount().

Note that when you are using integer arithmetic you must ensure that the precision loss is not too big as the progress is always smaller than or equal to the total count. So you should use progressInPercent=progressInBytes*100/totalNumberOfBytes.

Note that when you are using Swing, there are already the classes ProgressMonitor and ProgressMonitorInputStream providing a similar functionality.

OTHER TIPS

Ok thanks anyway. i just solved it by showing a wait cursor via

component.setCursor(new Cursor(Cursor.WAIT_CURSOR));

and back

component.setCursor(Cursor.getDefaultCursor());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top