Android how to improve the download speed - java

My code download speed to reach the desired effect,how to improve the download speed
The code is as follows:
URL url = new URL("www.google.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream inStream = conn.getInputStream();
RandomAccessFile threadfile = new RandomAccessFile(saveFile, "rwd");
byte[] buffer = new byte[8192];
int byteCount= 0;
while((byteCount = inStream.read(buffer)) != -1){
threadfile.write(buffer,0,byteCount);
}

Your download speed will only be as fast as the bandwidth supplied to you by the ISP in use and the rate at which the server you request from sends back to you. Your code is fine, the speed depends primarily on the ISP.

Related

Send a file with a PUT request using a HttpURLConnection

I'm trying to do something relatively simple. I need to make a simple PUT request with a file in the body in order to upload a file to a server not in my control. Here's the code I have so far:
connection = ((HttpURLConnection)new URL(ticket.getEndpoint()).openConnection());
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "video/mp4");
connection.setRequestProperty("Content-Length", String.valueOf(getStreamFile().length()));
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.connect();
outputStream = connection.getOutputStream();
streamFileInputStream = new FileInputStream(getStreamFile());
streamFileBufferedInputStream = new BufferedInputStream(streamFileInputStream);
byte[] streamFileBytes = new byte[getBufferLength()];
int bytesRead = 0;
int totalBytesRead = 0;
while ((bytesRead = streamFileBufferedInputStream.read(streamFileBytes)) > 0) {
outputStream.write(streamFileBytes, 0, bytesRead);
outputStream.flush();
totalBytesRead += bytesRead;
notifyListenersOnProgress((double)totalBytesRead / (double)getStreamFile().length());
}
outputStream.close();
logger.debug("Wrote {} bytes of {}, ratio: {}",
new Object[]{totalBytesRead, getStreamFile().length(),
(double)totalBytesRead / (double)getStreamFile().length()});
I'm watching my network manager and nothing near the size of my file gets sent. In fact, I don't know if anything is being sent at all, but I don't see any errors thrown.
I need to be able to send this request and also measure the status of the upload synchronously, so as to be able to inform my listeners of the upload progress. How can I modify my existing example to just work™?
Try setting the content-type param to multipart/form-data. W3C forms.

Socket exception on downloading big file

My app needs to download large files. After some time I get
java.net.SocketException: Connection timed out
I believe it's because the device is going to sleep or wifi.
So how i should handle this ? I want that user could download a large file no matter how much time it will take.
File downloading is done using:
HttpURLConnection con = (HttpURLConnection) new URL(uriToFile).openConnection();
con.connect();
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = con.getInputStream();
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
Thanks.
You can't handle it, other than by retrying the connection. You can lower the default connection timeout of about 75 seconds, but you can't raise it.

Need help optimising bufferedReader output

I am sending a file to the browser in a servlet. The highest JDK I can use is 1.4.2, and I also have to retrieve the file via a URL. I am also trying to use "guessContentTypeFromStream", but I keep getting null which raises an exception when used in the code sample below. I currently have to hard code or work out the content-type myself.
What I would like to know is, how I can re-factor this code so the file transmission is as fast as possible and also use guessContentTypeFromStream ? (Note "res" is HttpServletResponse).
URL servletUrl = new URL(sFileURL);
URLConnection conn = servletUrl.openConnection();
int read;
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
String sContentType =conn.guessContentTypeFromStream(conn.getInputStream());
res.setContentType(sContentType);
//res.setContentType("image/jpeg");
PrintWriter os = res.getWriter();
while((read = bis.read()) != -1){
os.write(read);
}
//Clean resources
os.flush();
This is how you normally read/writes data.
in = new BufferedInputStream(socket.getInputStream(), BUFFER_SIZE);
byte[] dataBuffer = new byte[1024 * 16];
int size = 0;
while ((size = in.read(dataBuffer)) != -1) {
out.write(dataBuffer, 0, size);
}

Android copying large inputstream to file very slow

I have an app that is downloading a zip file and then copying this file to a temporary file on the sd card on the phone, but it is being very very slow.
InputStream in = new BufferedInputStream(url.openStream(), 1024);
File tempFile = File.createTempFile("arc", ".zip", targetDir); //target dir is a file
String tempFilePath = tempFile.getAbsolutePath();
OutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile));
//copying file (in different void)
byte[] buffer = new byte[8192];
int len;
len = in.read(buffer);
enter code here
//it loops here for AGES
while (len >= 0) {
out.write(buffer, 0, len);
len = in.read(buffer);
}
in.close();
out.close();
My file is about 20MB, initially I had the buffer size of 1024, and changed it to 8192 thinking it may speed it up but it seemed to make no difference? I always finishes, and I get no errors it just takes ages!
I have searched to try and find a solution but I'm not coming up with anything so I may be going about this totally the wrong way?
Can anyone see what I'm doing wrong?
Bex
Donot increase buffer size. That may cause your application MemoryOutOfBoundsException.
There are varous factors for which your download will be slow. Weak internet connection, Weak file transfer and receiveing mode is also responsible. It also depend on capacity of device. Check whether you are using following code to create inputstream
URL u = new URL("enter url url here");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
Thanks
Deepak

HttpsURLConnection stalling out when getInputStream() is called

[Java 1.5; Eclipse Galileo]
HttpsURLConnection seems to stall when the getInputStream() method is called. I've tried using different websites to no avail (currently https://www.google.com). I should point out I'm using httpS.
The code below has been modified based on what I've learned from other StackOverflow answers. However, no solutions I've tried thus far have worked.
I'd be very grateful for a nudge in the right direction :)
public static void request( URL url, String query )
{
try{
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
//connection.setReadTimeout( 5000 ); //<-- uncommenting this line at least allows a timeout error to be thrown
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
System.setProperty("http.keepAlive", "false");
connection.setRequestMethod( "POST" );
// setting headers
connection.setRequestProperty("Content-length",String.valueOf (query.length()));
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); //WAS application/x-www- form-urlencoded
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)");
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
System.out.println( "THIS line stalls" + connection.getInputStream() );
////////////////////////////////////////////////////////////////////////////////////
}catch( Exception e ) {
System.out.println( e );
e.printStackTrace();
}
Typical errors look like:
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:782)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:739)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:313)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:681)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:626)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:983)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at https_understanding.HTTPSRequest.request(HTTPSRequest.java:60)
at https_understanding.Main.main(Main.java:17)
connection.setDoOutput(true);
This means that you have to open, write to, and close the connection's output stream before you attempt to read from its input stream. See the docs.
I reproduced the problem in Android 2.2: when downloading from a web-server over wireless and a HTTPS URL, the error is a socket "read time out" at URLConnection.getInputStream()
To fix it, use url.openStream() for the InputStream instead of connection.getInputStream()
Bonus: you can get the length of the file you're downloading so you can show a % complete indicator
code sample:
private final int TIMEOUT_CONNECTION = 5000;//5sec
private final int TIMEOUT_SOCKET = 30000;//30sec
file = new File(strFullPath);
URL url = new URL(strURL);
URLConnection ucon = url.openConnection();
//this timeout affects how long it takes for the app to realize there's a connection problem
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);
//IMPORTANT UPDATE:
// ucon.getInputStream() often times-out over wireless
// so, replace it with ucon.connect() and url.openStream()
ucon.connect();
iFileLength = ucon.getContentLength();//returns -1 if not set in response header
if (iFileLength != -1)
{
Log.i(TAG, "Expected Filelength = "+String.valueOf(iFileLength)+" bytes");
}
//Define InputStreams to read from the URLConnection.
// uses 5KB download buffer
InputStream is = url.openStream();//ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
outStream = new FileOutputStream(file);
bFileOpen = true;
byte[] buff = new byte[5 * 1024];
//Read bytes (and store them) until there is nothing more to read(-1)
int total=0;
int len;
int percentdone;
int percentdonelast=0;
while ((len = inStream.read(buff)) != -1)
{
//write to file
outStream.write(buff,0,len);
//calculate percent done
if (iFileLength != -1)
{
total+=len;
percentdone=(int)(total*100/iFileLength);
//limit the number of messages to no more than one message every 10%
if ( (percentdone - percentdonelast) > 10)
{
percentdonelast = percentdone;
Log.i(TAG,String.valueOf(percentdone)+"%");
}
}
}
//clean up
outStream.flush();//THIS IS VERY IMPORTANT !
outStream.close();
bFileOpen = false;
inStream.close();
Also don't set the content-length header. Java will do that for you.

Categories

Resources