Pause download in Java? - java

I'm using this code to download a file, and I was wondering if its possible to pause the download and then resume it later, and if so how?:
URL url = new URL(URL);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
lenghtOfFile /= 100;
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(Path + FileName);
byte data[] = new byte[1024];
long total = 0;
int count = 0;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
total += count;
}
output.flush();
output.close();
input.close();

This is only possible if the server supports HTTP range headers (introduced in HTTP 1.1)
See this question for examples in Java: how to use the HTTP range header in J2ME?.
"Pausing" could just mean reading some of the stream and writing it to disk. When resuming you would have to use the headers to specify what is left to download.

I think the support for the resume is at the server side, the clients cannot direct it.

Related

Android Partially Downloaded Files Report Wrong File Size

I'm putting together some code to download files from an HTTP address in Android. I'd like to support download resumption if the download fails mid way.
The output I get when starting the download, then killing the wifi connection and restarting again several times is the following:
Start size 0
Stop size 12333416
Start size 12333416
Stop size 16058200
Start size 3724784
I cannot understand why after the first resumption, subsequent file size readings of the partially downloaded file do not match.
Thanks in advance!
public void download(String source, String target) throws IOException {
BufferedOutputStream outputStream = null;
InputStream inputStream = null;
try {
File targetFile = new File(target);
currentBytes = targetFile.length();
Log.i(TAG, "Start size " + String.valueOf(currentBytes));
outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));
// create the input stream
URLConnection connection = (new URL(source)).openConnection();
connection.setConnectTimeout(mCoTimeout);
connection.setReadTimeout(mSoTimeout);
inputStream = connection.getInputStream();
inputStream.skip(currentBytes);
// calculate the total bytes
totalBytes = connection.getContentLength();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) > 0) {
// write the bytes to file
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
currentBytes += bytesRead;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
// close the output stream
outputStream.flush();
outputStream.close();
}
if (inputStream != null) {
// close the input stream
inputStream.close();
}
Log.i(TAG, "Stop size " + String.valueOf(currentBytes));
}
}
There are two things you are doing wrong:
To resume download to file you should append, not rewrite the file. Use special constructor for output stream:
FileOutputStream(targetFile, true)
To request part of file from server you should use HTTP 1.1 property "Range". You can do it like this:
HttpURLConnection httpConnection = (HttpURLConnection) connection;
connection.setRequestProperty("Range", "bytes=" + currentBytes + "-");

Upload image on a web site using Java

Is there any possibility to upload a file (for example: an image), to a site and to calculate the transfer rate?
I have some code that downloads an image from a specified url and calculates the transfer rate, using the java.net.Url class, something like:
long startTime = System.currentTimeMillis(); //start time
System.out.println("Connecting site...\n");
System.out.println("Downloading......");
URL url = new URL("http://....");
url.openConnection();
InputStream reader = url.openStream();
FileOutputStream writer = new FileOutputStream("D:/imagine.jpg");
byte[] buffer = new byte[153600];
int totalBytesRead = 0;
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
totalBytesRead += bytesRead;
}
long endTime = System.currentTimeMillis();//end of download
long elapsedTime=(endTime-startTime)/1000;//from miliseconds in seconds
System.out.println("ElapsedTime is " +elapsedTime +" s");
int memory=new Integer(totalBytesRead);
double memoryFinal=memory * 0.0009765625; //file in Kb
System.out.println("File size: " +memoryFinal +"Kb");
System.out.println("Speed :" + memoryFinal/elapsedTime + "Kbps");
writer.close();
reader.close();
I need something easy and useful. Thank you.
Yes you can - but it is not simple.
POSTing a file to a server is not implemented in plain java URLConnection, but you have to implements the protocol.
Or, You can use org.apache.commons.httpclient
http://www.theserverside.com/news/1365153/HttpClient-and-FileUpload
I recommend the library Apache FileUpload.
You can implement a progress bar too. See this .
Regards

Download file from ftp server

i am writing a small android application which requires some data which is stored on my web server. The file is a .txt file curretly less than 1 MB. Is it advisable to set up a ftp server to get the data or can i just use a http get method to get the contents on a file. If i am using a http get can someone please tell me the java code required for this operation.
This is out of my head (so an error could have sneaked in):
URL url = new URL("http://www.yourserver.com/some/path");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
FileOutputStream out = new FileutputStream("/path/to/your/output/file");
byte[] buffer = new byte[16384];
int len;
while((len = in.read(buffer)) != -1){
out.write(buffer, 0, len);
}
finally {
urlConnection.disconnect();
}

Updating progress dialog

I am trying to make an application that can help me to evaluate the time to download the file from a web resource. I have found 2 samples:
Download a file with Android, and showing the progress in a ProgressDialog
and
http://www.helloandroid.com/tutorials/how-download-fileimage-url-your-device
The second example shows a smaller download time, but I cannot understand how to update progress dialog using it. I think something should be done with "while" expression in second case, but I cannot find what. Could someone give me any piece of advice?
UPD:
1st code:
try {
time1 = System.currentTimeMillis();
URL url = new URL(path);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/analyzer/test.jpg");
byte data[] = new byte[1024];
long total = 0;
time11 = System.currentTimeMillis();
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
time22= System.currentTimeMillis()-time11;
output.flush();
output.close();
input.close();
} catch (Exception e) {}
timetaken = System.currentTimeMillis() - time1;
2nd code:
long time1 = System.currentTimeMillis();
DownloadFromUrl(path, "test.jpg");
long timetaken = System.currentTimeMillis() - time1;
Where
public void DownloadFromUrl(String imageURL, String fileName) { //this is the downloader method
try {
URL url = new URL(imageURL); //you can write here any link
File file = new File(fileName);
/*Open a connection to that URL. */
URLConnection ucon = url.openConnection();
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(PATH+file);
fos.write(baf.toByteArray());
fos.close();
} catch (IOException e) {
Log.d("ImageManager", "Error: " + e);
}
So the thing is that first method seems to be slower for about 30%.
The second example may run faster, but it monopolizes the GUI thread. The first approach, using AsyncTask, is better; it allows the GUI to stay responsive as the download proceeds.
I found it helpful to compare AsyncTask with SwingWorker, as shown in this example.
first link is best. But i can't provide code( it's home comp) in monday or later i can provide full function. But :
private class DownloadFile extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... url) {
int count;
try {
URL url = new URL(url[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
this class are best for it ( imho) . publishProgress it's simple function where u have max two lines. Set max and set current. How u can see in this code lenghtOfFile it's how many bytes have ur file. total-current progress ( example 25 from 100 bytes) . Run this class easy : DownloadFile a = new DownloadFile(); a.execute(value,value);//or null if u not using value. Hope u understand me , im not good speaking on english.

How do I download part of a file using Java?

I'm using this Java code to download a file from the Internet:
String address = "http://melody.syr.edu/pzhang/publications/AMCIS99_vonDran_Zhang.pdf";
URL url = new URL(address);
System.out.println("Opening connection to " + address + "...");
URLConnection urlC = url.openConnection();
urlC.setRequestProperty("User-Agent", "");
urlC.connect();
InputStream is = urlC.getInputStream();
FileOutputStream fos = null;
fos = new FileOutputStream("myFileName");
int oneChar, count = 0;
while ((oneChar = is.read()) != -1) {
System.out.print((char)oneChar);
fos.write(oneChar);
count++;
}
is.close();
fos.close();
System.out.println(count + " byte(s) copied");
I'd like to know if there is a way for me to download only a part of a file.
For example, for a 5MB file to download the last 2MB.
If the server supports it (and HTTP 1.1 servers should), you can use range requests:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
Also, reading one character at a time is hugely inefficient - you should be reading in blocks, say 4, 16 or 32 KB.
Please have a look at Java: resume Download in URLConnection

Categories