I'm trying to use the following code to download and then eventually view a PDF file. The URL of the file is like this:
http://www.example.com/directory/something.example.com This File.pdf
I've tried replacing the spaces with %20, I've tried "UrlEncoder.encode", no matter what I get either FileNotFoundException or MalformedURLException (when encoding the URL). Example exceptions:
java.io.FileNotFoundException:
http://www.example.com/directory/something.example.com This File.pdf
java.io.FileNotFoundException:
http://www.example.com/directory/something.example.com%20This%20File.pdf
java.net.MalformedURLException: Protocol not found:
http%3A%2F%2Fwww.example.com%directory%2Fsomething.example.com+This+File.pdf
If I copy those paths into any browser it downloads fine.
File file;
try
{
String urlString =
"http://www.example.com/directory/something.example.com This File.pdf"
URL url = new URL(urlString);
//URL url = new URL(URLEncoder.encode(urlString, "UTF-8"));
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
file = new File(getExternalFilesDir(null), "test.pdf");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[1024 * 1024];
int bufferLength;
while ((bufferLength = inputStream.read(buffer)) > 0)
{
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.flush();
fileOutput.close();
inputStream.close();
return file.getAbsolutePath();
}
catch (Exception e)
{
Log.e(getClass().getSimpleName(), e.getMessage(), e);
return "";
}
The exception java.io.FileNotFoundException will be returned if the server responds with a 404 error code. Sometimes the error code and the data returned do not match. You can check for this (and get whatever data was returned) using the following:
boolean isError = urlConnection.getResponseCode() >= 400;
InputStream inputStream = = isError ? urlConnection.getErrorStream() : urlConnection.getInputStream();
And if you're connecting to a non-standard port, you can fix it by adding these headers to your request:
urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept","*/*");
Your UrlEncoder attempts have been wrong. Here's the javadoc:
http://docs.oracle.com/javase/6/docs/api/java/net/URLEncoder.html
java.io.FileNotFoundException:
http://www.example.com/directory/something.example.com This File.pdf
Spaces were not encoded so it doesn't match your file.
java.io.FileNotFoundException:
http://www.example.com/directory/something.example.com%20This%20File.pdf
%20 are valid url symbols, so this also doesn't match your file.
java.net.MalformedURLException: Protocol not found:
http%3A%2F%2Fwww.example.com%directory%2Fsomething.example.com+This+File.pdf
Slash after .com is not encoded properly. Results in an incorrectly encoded url.
With UrlEncoder, you should be encoding the file name and concatenating it with the URL, not encoding the entire url string and use UTF-8 encoding. Anything else (not UTF-8) is not guaranteed to work.
If manually encoding spaces don't then pass them through the UrlEncoder.
Related
I am downloading HTML file from server using URLConnection but I am getting FileNotFoundException. My path is correct. Using same code same file is downloaded on android of API level 25 but on API level less than it is not downloading. Also connection.getContentLength(); is giving 311 value always. I am not getting any answer to solve this. I am hereby adding my code.
My class file code is
String HomeScreenResourcefilename = WebHomescreenResObj.getString("FileName");
int ProductTargetID = WebHomescreenResObj.getInt("ProductTargetID");
String WebURL_Part1 = context.getResources().getString(R.string.FileDownloadRootPath)+"/ExhibitorData/";
String WebURL_Part2 = GlobalVariables.tradeShowName+" - "+GlobalVariables.exhibitorName+"/HTMLHomeScreen/"+ProductTargetID +"/"+HomeScreenResourcefilename;
String WebURL = WebURL_Part1 + WebURL_Part2;
try {
URL url = new URL(WebURL);
File file = new File(context.getFilesDir(), HomeScreenResourcefilename);
URLConnection connection = url.openConnection();
connection.connect();
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = connection.getInputStream();
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
} catch (Exception e1) {
e1.printStackTrace();
LogE("error in 14 :"+e1);
}
Use HttpURLConnection and then connection.getResponseCode() to get the status code. If it is greater than 400, that might be the reason.
Update: Use url encoding.
In My android Application i have a list of song.User can download any of song from it.
But my problem is when i download a file using http request it return content length = 0 or -1 so i can not download file.
When i use same url in browser then song downloaded completely.
My code to download a song file is -
URL url = new URL(mUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setConnectTimeout(TimeOut);
connection.setReadTimeout(TimeOut);
connection.connect();
int lenghtOfFile = connection.getContentLength();
and file length is either 0 or -1.
What the problem in my code.
Thanks in advance.
The best way to run an Http Request wheter download or upload is to use AsycTask in order to split the download task from your UI,
try to download your file by putting this code in a method and call it, if your using an AsyncTask you can add a progressBar and update it's progression from the below given code
to update progress uncomment
updateProgress(downloadedSize,totalSize);
try {
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
URL url = new URL("File Url");
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,"song.extension");
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
int totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
//updateProgress(downloadedSize, totalSize); if your run this code from AsyncTask
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
i have this url http://app.oviewz.com/proceso_seleccions/110.png?style=medium&token=q9W0BQpU. when u put on any web browser automatically download the file
but when i try to download by using this android code:
String urllogo="http://app.oviewz.com/proceso_seleccions/110.png?style=medium&token=q9W0BQpU";
URL url = new URL(urllogo);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
// <span id="IL_AD2" class="IL_AD">connect</span>
urlConnection.connect();
// set the path where we want to save the file
File SDCardRoot = Environment.getExternalStorageDirectory();
// create a new file, to save the <span id="IL_AD7"
// class="IL_AD">downloaded</span> file
File file = new File(SDCardRoot, "logo.jpg");
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 <span
// id="IL_AD12" class="IL_AD">downloading</span>
// create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
// close the output stream when complete //
fileOutput.close();
is raised FileNotFoundException. anyone can help me what i'm doing wrong?
When I open this URL in my browser, it redirects me to http://app.oviewz.com/. This means that the image is not available publicly i.e. You need to be logged in to view the image. So, you can't directly download the image using URL. If the website has some API for login, you can use that to get required access token and send the same in header of this request, the way they do in facebook or g+ API.
I am working on an API which returns me a zip file containing multiple XML files, which i have to parse individually after extracting the zip file.
Here is the link for that(will download the zip-file) :
http://clinicaltrials.gov/ct2/results?term=&recr=&rslt=&type=&cond=&intr=&outc=&lead=&spons=&id=&state1=&cntry1=&state2=&cntry2=&state3=&cntry3=&locn=&gndr=Female&age=0&rcv_s=&rcv_e=&lup_s=&lup_e=studyxml=true
Here is my current code to save the zip-file in sdcard:
File root = Environment.getExternalStorageDirectory();
String url= "http://clinicaltrials.gov/ct2/results?term=&recr=&rslt=&type=&cond=&intr=&outc=&lead=&spons=&id=&state1=&cntry1=&state2=&cntry2=&state3=&cntry3=&locn=&gndr=Female&age=0&rcv_s=&rcv_e=&lup_s=&lup_e=xml=true";
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.setConnectTimeout(10000); // timeout 10 secs
conn.connect();
InputStream input = conn.getInputStream();
FileOutputStream fOut = new FileOutputStream(new File(root, "new.zip"));
int byteCount = 0;
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = input.read(buffer)) != -1) {
fOut.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
Problem :
New.zip File is getting created in sdcard but it seems nothing is downloading also the file size is 0kb.
Is my code proper or I have to use something else to handel zipfiles.
Edit Solved :
I am extremely sorry the api link is invalid ... it should be
http://clinicaltrials.gov/ct2/results?term=&recr=&rslt=&type=&cond=&intr=&outc=&lead=&spons=&id=&state1=&cntry1=&state2=&cntry2=&state3=&cntry3=&locn=&gndr=Female&age=0&rcv_s=&rcv_e=&lup_s=&lup_e=&studyxml=true
& is required before studtxml..
Thnx every 1 for quick response ..
There is something wrong either in your .zip file URL or in .zip file size(0 byte size) because if we download this .zip file (From URL given by you) from web browser then also its downloaded with 0 byte size.
Downloaded .zip file URL.
Your Url in the code String url=... is not giving me a zip file.
http://clinicaltrials.gov/ct2/results?term=&recr=&rslt=&type=&cond=&intr=&outc=&lead=&spons=&id=&state1=&cntry1=&state2=&cntry2=&state3=&cntry3=&locn=&gndr=Female&age=0&rcv_s=&rcv_e=&lup_s=&lup_e=xml=true
The link you provided is different
http://clinicaltrials.gov/ct2/results?term=&recr=&rslt=&type=&cond=&intr=&outc=&lead=&spons=&id=&state1=&cntry1=&state2=&cntry2=&state3=&cntry3=&locn=&gndr=Female&age=0&rcv_s=&rcv_e=&lup_s=&lup_e=studyxml=true
Looks like there's an error: lup_e=xml=true should be lup_e=studyxml=true
I'm working on a project where the url sometimes can have empty spaces in it (not always) example: www.google.com/ example/test.jpg and sometimes www.google.com/example/test.jpg.
My code:
try {
URL url = new URL(stringURL);
URLConnection conexion = url.openConnection();
conexion.connect();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream(), 8192);
OutputStream output = new FileOutputStream(fullPath.toString());
byte data[] = new byte[1024];
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
It's this line that fails: InputStream input = new BufferedInputStream(url.openStream(), 8192);
with a: java.io.FileNotFoundException.
I've tryed to encode the specific line but here is the kicker: the server needs the empty space " " in order to find the file, so I need to have the empty space somehow. I can find the file (jpg) if i use firefox browser.
Any help much appreciated.
Edit update:
Well now I've tryed to encode every single bit after the host part of the url to utf-8 and I've tryed using both + and %20 for blank space. Now I can manage to DL the file but it will be faulty so it can't be read.
Edit update2:
I had made a mistake with %20, that works.
Okay I solved the headache.
First I use:
completeUrl.add(URLEncoder.encode(finalSeperated[i], "UTF-8"));
For every part of the url between "/"
Then I use:
ArrayList<String> completeUrlFix = new ArrayList<String>();
StringBuilder newUrl = new StringBuilder();
for(String string : completeUrl) {
if(string.contains("+")) {
String newString = string.replace("+", "%20");
completeUrlFix.add(newString);
} else {
completeUrlFix.add(string);
}
}
for(String string : completeUrlFix) {
newUrl.append(string);
}
To build a proper urlString.
The reason this works is because http needs %20. See Trouble Percent-Encoding Spaces in Java comment by Powerlord