Resume http download. File appends, but size is bigger - java

URL url;
url = new URL("http://download.thinkbroadband.com/5MB.zip");
File fileThatExists = new File("/sdcard/testfile");
URLConnection conexion = url.openConnection();
conexion.setRequestProperty("Range", "bytes=" + fileThatExists.length() + "-");
// Resume download.
conexion.setRequestProperty("If-Range", "Mon, 02 Jun 2008 15:30:42 GMT");
conexion.connect();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/testfile", true);
byte data[] = new byte[1024];
long total = 0;
int i = 0;
while ((count = input.read(data)) != -1) {
total += count;
i++;
output.write(data, 0, count);
}
}
I tried to resume download. But If my file is 5200kb, and I resume download after 100kb, I got file 5300kb. What's wrong with this code?

Related

File download incomplete when application killed or destroy

When I am downloading a file from the server if suppose I killed or destroy the application means it will download only half of data how to resume download when application open or how to delete incomplete data in the file.
Any ideas?
private void downloadBookDetails(String pMainFolder, String pFileName, String pDownloadURL) {
Log.i(TAG, "Coming to this downloadBookDetails ");
try {
URL url = new URL(pDownloadURL);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File directory = new File(pMainFolder, pFileName);
FileOutputStream outStream = new FileOutputStream(directory);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch (Exception e) {
//Add Network Error.
Log.e(TAG, "Download Error Exception " + e.getMessage());
e.printStackTrace();
}
}
You should use DownLoad Manager for downloads in your app. This will automatically handles all the things for you. Which is a system service that can handle long-running HTTP downloads.
UPDATE
If you want to download the file by your own then you can use it like below:
#SuppressLint("Wakelock")
#Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wl.acquire();
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
File SDCardRoot = Environment.getExternalStorageDirectory();
File file = new File(SDCardRoot,"/"+fileName);
int downloaded=0;
if(file.exists()){
downloaded=(int) file.length();
connection.setRequestProperty("Range", "bytes=" + (int) file.length() + "-");
}
else{
file.createNewFile();
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength()+(int)file.length();
// download the file
input = connection.getInputStream();
if(downloaded>0){
output = new FileOutputStream(file,true);
}
else{
output = new FileOutputStream(file);
}
byte data[] = new byte[1024];
long total = downloaded;
int count;
mProgressDialog.setMax(fileLength/1024);
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled())
return null;
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int)total/1024);
output.write(data, 0, count);
}
output.flush();
if (output != null)
output.close();
if (input != null)
input.close();
if (connection != null)
connection.disconnect();
wl.release();
return null;
} catch (Exception e) {
return e.toString();
}
}
catch (Exception e) {
return e.toString();
}
}

Exeception get inputStream from connection 404 responce and file not found exception?

I want to try download a file from resume in android studio, i have try my code with open stream and don't have any problem but in this code:
public void startStream2(Context context) {
try {
URL url = new URL(file.getFileUrl());
StrictMode.ThreadPolicy ploicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(ploicy);
URLConnection connection = url.openConnection();
int downloaded = 0;
BufferedOutputStream bout;
f = new File(downloadPath, file.getName());
if (f.exists()) {
downloaded = (int) f.length();
connection.setRequestProperty("Range", "bytes=" + (f.length()) + "-");
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","*/*");
connection.connect();
int response=((HttpURLConnection)connection).getResponseCode();
Log.e(TAG, "startStream2: "+ response );
if (response>399 && response<601){
InputStreamReader sr;
sr = new InputStreamReader(((HttpURLConnection) connection).getErrorStream(), "UTF-8");
StringBuilder builder = new StringBuilder();
for (int bt = 0; (bt = sr.read()) != -1;) {
builder.append((char)bt);
}
sr.close();
Log.e(TAG, "startStream2: "+builder.toString());
}
InputStream inp=connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(inp);
stream2 = (downloaded == 0) ? new FileOutputStream(f) : new FileOutputStream(f, true);
bout = new BufferedOutputStream(stream2, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
int percent = ((int) downloaded * 100) / (int) Size;
//set percent progress
}
}catch (Exception e){
Log.e(TAG, "startStream2: ",e );
}
}
Error log:
startStream2: 405 startStream2:
405 Not Allowed
405 Not Allowed
nginx
startStream2:
java.io.FileNotFoundException:
at
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:242)
I have test the url before and don't have any problem with download from first or resume.
How can i resolve it?
thanks.
connection.setDoOutput(true);
The problem is here. It changes the HTTP verb from GET to POST. You don't want to POST. You aren't sending any output. Remove it.
And if the response code isn't 200 you should not get the input stream, otherwise it will throw an exception. You can get the error stream if you want more info, but there isn't an input stream at this point.
You can also remove
connection.connect();
and
connection.setDoInput(true);
They don't do anything that doesn't already happen.
remove these lines
connection.setDoInput(true);
connection.setDoOutput(true);
Finally i have resolved it by this code:
public void startStream2(Context context) {
try {
URL url = new URL(file.getFileUrl());
StrictMode.ThreadPolicy ploicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(ploicy);
URLConnection connection = url.openConnection();
int downloaded = 0;
BufferedOutputStream bout;
f = new File(downloadPath, file.getName());
if (f.exists()) {
downloaded = (int) f.length();
connection.setRequestProperty("Range", "bytes=" + (f.length()) + "-");
}
connection.setDoInput(true);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","*/*");
int response=((HttpURLConnection)connection).getResponseCode();
Log.e(TAG, "startStream2: "+ response );
if (response>399 && response<601){
InputStreamReader sr;
sr = new InputStreamReader(((HttpURLConnection) connection).getErrorStream(), "UTF-8");
StringBuilder builder = new StringBuilder();
for (int bt = 0; (bt = sr.read()) != -1;) {
builder.append((char)bt);
}
sr.close();
Log.e(TAG, "startStream2: "+builder.toString());
}
InputStream inp=connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(inp);
stream2 = (downloaded == 0) ? new FileOutputStream(f) : new FileOutputStream(f, true);
bout = new BufferedOutputStream(stream2, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
int percent = ((int) downloaded * 100) / (int) Size;
//set percent progress
}
}catch (Exception e){
Log.e(TAG, "startStream2: ",e );
}
}
Thank a lot!

Transferring Files via TCP/IP works in Windows but not Ubuntu

I was trying my hands at sending multiple files using TCP/IP connection with the help of this guide.
When I execute my testClient codes from Ubuntu 14.04, files are transferred over to testServer in Windows 7. The .txt files received here are in correct format.
However, when I execute testClients codes from Windows 7 and testServer from Ubuntu 14.04, the files received in Ubuntu 14.04 was messed up. (The contents from txt#2 contents spill over to txt#1.)
During the swap, none of the codes in both testServer and testClients were changed other than their IP address and file location.
I am confused. Why did the codes work fine in Windows 7 but not in Ubuntu? Is there something wrong with my codes? I would appreciate any help on this.
TestServer.java
public static void main(String[] args) throws IOException {
FileOutputStream fos;
BufferedOutputStream bos;
OutputStream output;
DataOutputStream dos;
int len;
int smblen;
InputStream in;
boolean flag = true;
DataInputStream clientData;
BufferedInputStream clientBuff;
ServerSocket serverSocket = new ServerSocket(5991);
serverSocket.setSoTimeout(500000);
System.out.println("Waiting for client on port " + serverSocket.getLocalPort());
Socket clientSocket = null;
clientSocket = serverSocket.accept();
System.out.println("Just connected to " + clientSocket.getRemoteSocketAddress());
while (true){
while(flag==true) {
in = clientSocket.getInputStream();
clientData = new DataInputStream(in);
clientBuff = new BufferedInputStream(in);
int fileSize = clientData.read();
if (fileSize != 0)
System.out.println("Receiving " + fileSize + " files.\n");
//Store filenames and file sizes from client directory
ArrayList<File>files=new ArrayList<File>(fileSize);
ArrayList<Integer>sizes = new ArrayList<Integer>(fileSize);
//Server accepts filenames
for (int count=0; count<fileSize; count ++){
File ff=new File(clientData.readUTF());
files.add(ff);
}
for (int count=0; count<fileSize; count ++){
sizes.add(clientData.readInt());
}
for (int count=0; count<fileSize; count++) {
if (fileSize - count == 1) {
flag = false;
}
len = sizes.get(count);
output = new FileOutputStream("/home/pp/Desktop/inResources/" + files.get(count));
dos = new DataOutputStream(output);
bos = new BufferedOutputStream(output);
byte[] buffer = new byte[1024];
bos.write(buffer, 0, buffer.length);
while (len > 0 && (smblen = clientData.read(buffer)) > 0) {
dos.write(buffer, 0, smblen);
len = len - smblen;
dos.flush();
}
dos.close();
System.out.println("File " + files.get(count) + " with " + sizes.get(count) + " bytes recieved.");
}
}
if (flag == false) {
System.out.println("\nTransfer completed. Closing socket...");
serverSocket.close();
break;
}
}
}
TestClient.java
public static void main(String[] args) throws IOException {
String serverName = "192.168.1.12"; //IP address
int port = 5991;
Socket sock = new Socket(serverName, port);
System.out.println("Connected to " + serverName + " on port " + port + "\n");
File myFile = new File("C:\\Users\\inter2\\Desktop\\noobs\\outResources");
File[] files = myFile.listFiles();
OutputStream os = sock.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//Sending total number of files in folder
dos.writeInt(files.length);
//Sending file names
for (int count=0; count<files.length; count++) {
dos.writeUTF(files[count].getName());
}
//Sending file sizes
for (int count=0; count<files.length; count++) {
int filesize = (int) files[count].length();
dos.writeInt(filesize);
}
//Sending of files
for (int count=0; count<files.length; count ++) {
int filesize = (int) files[count].length();
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(files[count].toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length);
dos.write(buffer, 0, buffer.length);
dos.flush();
System.out.println("Sending file " + files[count].getName() + " with " + filesize + " bytes.");
}
System.out.println("\n" + files.length + " files successfully transfered.");
sock.close();
}
This code never worked.
int fileSize = clientData.read();
Here you are reading the amount of files, as a byte.
dos.writeInt(files.length)
Here you are writing that amount, as an int. So already your writer is three bytes ahead of your reader.
Change read() to readInt() above.
Other notes:
Receiving:
byte[] buffer = new byte[1024];
This is OK but a bigger buffer would be more efficient, say 8192.
bos.write(buffer, 0, buffer.length);
This is a bug. Remove it. You are writing 1024 null bytes at the beginning of the file.
while (len > 0 && (smblen = clientData.read(buffer)) > 0) {
dos.write(buffer, 0, smblen);
len = len - smblen;
dos.flush();
Don't flush inside loops.
}
Sending:
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(files[count].toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length);
dos.write(buffer, 0, buffer.length);
No need to waste a buffer of the size of the file. Use the same code you use for receiving above.

File downloading - negative file length

I am trying to download a file (mp3) from my server.
I want to show the downloading progress, but I am facing a problem that whole time the file size is -1.
The screenshot:
My code:
try {
URL url = new URL(urls[0]);
// URLConnection connection = url.openConnection();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
int fileSize = connection.getContentLength();
if (fileSize == -1)
fileSize = connection.getHeaderFieldInt("Length", -1);
InputStream is = new BufferedInputStream(url.openStream());
OutputStream os = new FileOutputStream(myFile);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = is.read(data)) != -1) {
total += count;
Log.d("fileSize", "Lenght of file: " + fileSize);
Log.d("total", "Lenght of file: " + total);
// publishProgress((int) (total * 100 / fileSize));
publishProgress("" + (int) ((total * 100) / fileSize));
os.write(data, 0, count);
}
os.flush();
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
I get the garbage value for the fileSize which return -1 (int fileSize = connection.getContentLength();)
Inspect the headers the server is sending. Very probably the server is sending Transfer-Encoding: Chunked and no Content-Length header at all. This is a common practice in HTTP/1.1. If the server isn't sending the length, the client obviously can't know it. If this is the case, and you have no control over the server code, the best thing to do is probably display a spinner type of indicator only.

What should i use InputStream or FileInputStream or BufferedInputStream?

I am downloading few pdf and video file from the server and for that I am using InputStream to collect response but I want to know that which is better for my purpose InputStream or FileInputStream or BufferedInputStream ?
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(RootFile, fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
I am using this for downloading videos
void downloadFile(String vidN){
int downloadedSize = 0;
int totalSize = 0;
try {
// here vidN is the name of the file like bird.mp4
// here sitepath is the path of the file
URL url = new URL(sitepath+vidN);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect
urlConnection.connect();
//set the path where we want to save the file
String RootDir = Environment.getExternalStorageDirectory()
+ File.separator + "VideoNR2";
File RootFile = new File(RootDir);
RootFile.mkdir();
//create a new file, to save the downloaded file
File file = new File(RootDir,""+vidN);
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize = bufferLength;
}
//close the output stream when complete //
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
}
}

Categories

Resources