Muhammad Riyaz
Muhammad Riyaz

Reputation: 2942

DataOutputStream write progress not accurate

DataOutputStream wr = new DataOutputStream(
                    urlConnection.getOutputStream());
            fis = new FileInputStream(image_path);
            int total = 0;
            int bytes_read = 0;
            int buffer_size = 1024;
            byte[] buffer = new byte[buffer_size];
            bytes_read = fis.read(buffer, 0, buffer_size);
            int progress = 0;
            while (bytes_read > 0) {
                total += bytes_read;
                wr.write(buffer, 0, bytes_read);
                int bytes_available = fis.available();
                progress = (int) ((total * 100) / bytes.length);
                Log.i("asd", "direct progress: " + progress);
                buffer_size = Math.min(bytes_available, buffer_size);
                buffer = new byte[buffer_size];
                bytes_read = fis.read(buffer, 0, buffer_size);
            }
            Log.i("asd", "data written to target so far is: " + wr.size()+ " file length: "+bytes.length);
            wr.flush();
            wr.close();

Uploads the file completely onto server. But my intention is to get the progress of already uploaded bytes. I can get that also(which I think is inaccurate). When i run this code, It shows me progress from 0 to 100 but the file gets uploaded to server after 1 minute or so.

I have tried with files less than 1MB and the progress is accurate. But when the file is larger, I get the inaccuracy of progress problem.

Upvotes: 0

Views: 548

Answers (2)

Muhammad Riyaz
Muhammad Riyaz

Reputation: 2942

connection.setFixedLengthStreamingMode((int) requestLength);

will do the trick !

Upvotes: 2

Zielony
Zielony

Reputation: 16537

Your progress indicator is inaccurate because you're dividing (bytes read) by (bytes read in one read). It means that you're displaying number of reads as upload percentage which is incorrect and works only for files uploaded in 100 reads/writes.

You should read file length once at the beginning. Then accumulate total bytes read/written. Then progress equals:

progress = 100 * totalBytesWritten / fileLength

DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
fis = new FileInputStream(image_path);
int fileLength = new File(image_path).length();

int bytes_read = 0;
int bytesReadTotal = 0;
int buffer_size = 1024;
byte[] buffer = new byte[buffer_size];
int progress = 0;

while ((bytes_read = fis.read(buffer, 0, buffer_size)) > 0) {
     wr.write(buffer, 0, bytes_read);
     bytesReadTotal += bytes_read;
     progress = (int) (100.0f * bytesReadTotal / fileLength);
     Log.i("asd", "direct progress: " + progress);
}
Log.i("asd", "data written to target so far is: " + wr.size()+ " file length: "+bytes.length);
wr.flush();
wr.close();

You also don't have to recreate buffer each time you'd like to read/write something. You can reuse the old one.

Upvotes: 2

Related Questions