Reputation: 1
I am trying to upload a file on a server and display how many bytes are uploaded per second by this way:
public void RunUploadTest () {
try {
URL url = new URL(serverLink);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("content-type", "video/mp4");
for(int i =0; i<10; i++) {
FileInputStream fis = new FileInputStream(myFileVideo);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
int bytesWrite = 0;
byte[] buffer = new byte[512];
Stopwatch timer = new Stopwatch();
int read;
while ((read = fis.read(buffer)) != -1&& timer.elapsedTime()<1000) {
dos.write(buffer, 0, read);
dos.flush();
bytesWrite++;
}
Log.d("Upload", "Bytes written: " + bytesWrite*512);
}
fis.close();
} catch (IOException e){
e.printStackTrace();
}
}
The problem is that is not calculating how many bytes are uploaded as I expect. Do you have any idea why is not working?
Upvotes: 0
Views: 155
Reputation: 816
There are few problems with your code:
This is a relatively minor issue, but the last buffer you read/write will probably not going to be 512 bytes long, so your calculation will not be precise.
you should change
bytesWrite++;
}
Log.d("Upload", "Bytes written: " + bytesWrite*512);
to
bytesWrite += read;
}
Log.d("Upload", "Bytes written: " + bytesWrite);
The following condition:
while ((read = fis.read(buffer)) != -1&& timer.elapsedTime()<1000)
Will stop either when the file has finished reading, or 1 second elapsed. Unless a very small file, most likely file upload will stop after 1 second.
I'm not completely sure if you want an update every second, or just the average.
In case of average you should just change the while condition to:
while (read = fis.read(buffer))
And change log to:
float uploadRate = (float)(bytesWrite / timer.elapsedTime()) / 1000.0f;
String logString = String.format("Upload rate: %.2f bytes per second", uploadRate)
Log.d("Upload", logString);
In case you do want to print progress every second, you'll need to do something more fancy and expensive, like:
while (read = fis.read(buffer)) {
dos.write(buffer, 0, read);
dos.flush();
bytesWrite += read;
if (timer.shouldPrintSecondsProgress(){
Log.d("Upload", "Bytes written: " + bytesWrite);
}
}
StopWatch.shouldPrintSecondsProgress
should be something like:
public boolean shouldPrintSecondsProgress(){
int currentSecond = elapsedTime() / 1000;
if (currentSecond == nextUpdate){ //I've ignored the > case, which is probably an error in our case
nextUpdate++; //this is an int field, marking the next second cause update
return true;
}
return false;
}
While you are sending all your data and flushing the request stream, some layer of the networking stack might have buffer/async behavior. Actually the roundtrip alone might effect calculation correctness.
It best if you close the output stream prior to measure time elapsed, and/or read the response from server (which will ensure upload is finished).
Upvotes: 0
Reputation: 11
If you have 10 times the same bytes written, there are 2 options:
elapsedTime
method, returns in seconds(for example) and not in millisecondsYou probably don't need that for loop too, it makes you read the file 10 times.
I would rewrite your code like this:
public void RunUploadTest () {
try {
URL url = new URL(serverLink);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("content-type", "video/mp4");
FileInputStream fis = new FileInputStream(myFileVideo);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
int bytesWrite = 0;
byte[] buffer = new byte[512];
int read;
while((read = fis.read(buffer))) {
Stopwatch timer = new Stopwatch();
while (timer.elapsedTime()<1) { //my guess here is that this method returns in seconds
dos.write(buffer, 0, read);
dos.flush();
bytesWrite += read; //taken from Yoni Gross answer
}
Log.d("Upload", "Bytes written: " + bytesWrite);
}
fis.close();
} catch (IOException e){
e.printStackTrace();
}
}
Upvotes: 1