web-dev-qa-db-fra.com

HttpURLConnection Java.io.FileNotFoundException

Le code ci-dessous fonctionne très bien si je me connecte à ce qui semble être des serveurs Apache. Toutefois, lorsque je tente de me connecter à mon serveur .Net, une erreur est renvoyée. Je suppose que c'est une exigence d'en-tête, mais je n'arrive pas à obtenir une réponse satisfaisante, peu importe ce que j'essaie.

public String Download(String Url)
{
 String filepath=null;
 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(Url);
  //create the new connection
  HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

  //set up some things on the connection
  urlConnection.setRequestMethod("GET");
  urlConnection.setDoOutput(true); 
   //and 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.

  String filename= "effortback.png";   // you can download to any type of file ex:.jpeg (image) ,.txt(text file),.mp3 (audio file)
  Log.i("Local filename:",""+filename);
  File file = new File(SDCardRoot + "/",filename);

  //=====================================
  if(file.createNewFile())
  {
   file.createNewFile();
  }
  //=====================================

  //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[2048];
  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
   Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;

  }
  //close the output stream when done
  fileOutput.close();
  if(downloadedSize==totalSize)   filepath=file.getPath();

 //catch some possible errors...
 } catch (MalformedURLException e) {
  e.printStackTrace();
  Log.i("URL-ERROR:",e.toString());
 } catch (IOException e) {
  filepath=null;
  e.printStackTrace();
  Log.i("IO-ERROR:",e.toString());
 }
 Log.i("filepath:"," "+filepath) ;

 return filepath;

}

Les erreurs vont de:

Java.io.FileNotFoundException  //I always get this with either one of the below
   org.Apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:1061)

//or this one below
libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionTmpl.Java:186)

Il semble que peu importe ce que j'essaie, je ne peux pas le faire fonctionner. Encore une fois, cela fonctionne si j'essaye de télécharger une image de Google ou de certains autres sites, mais pas la totalité, mais certainement pas la mienne (.Net). Qu'est-ce que j'oublie ici? S'il vous plaît aider.

39
nathan

Vous pouvez obtenir FileNotFoundException parmi HttpUrlConnection (et OkHttpClient) si votre serveur renvoie> = HTTPStatus.BAD_REQUEST (400). Vous devez d'abord vérifier le code d'état pour savoir quel flux vous devez lire. 

int status = connection.getResponseCode();

if(status >= HttpStatus.SC_BAD_REQUEST)
    in = connection.getErrorStream();
else
    in = connection.getInputStream();

HttpStatus obsolète. La dernière syntaxe semble être:

            InputStream inputStream;

            int status = urlConnection.getResponseCode();

            if (status != HttpURLConnection.HTTP_OK)
                inputStream = urlConnection.getErrorStream();
            else
                inputStream = urlConnection.getInputStream();
96
Dori

Avait le même problème, résolu comme vous l'avez dit: 

urlConnection.setDoOutput(false);

Notez que vous devez le définir sur false car il est vrai par défaut.
Notez que vous devez le définir sur false car VolleyHurlStack le définissait à true.
Prends soin ;)

EDIT: Je viens de vérifier le code et par défaut, il est faux comme @ Abraham Abraham a dit. Mais je devais le définir sur false car si j'appelais getDoOutput(), il retournait true. J'ai trouvé que VolleyHurlStack le plaçait sur true. Donc, ma conclusion est setDoOutput à faux et cela fonctionnera.

package Java.net;
public abstract class URLConnection {
...

    /**
     * Specifies whether this {@code URLConnection} allows sending data.
     */
    protected boolean doOutput;

...
    public boolean getDoOutput() {
        return doOutput;
    }

    public void setDoOutput(boolean newValue) {
        checkNotConnected();
        this.doOutput = newValue;
    }
48
GuilhE

J'ai rencontré un problème dans lequel l'exécution d'une HEAD- Request a lancé une FileNotFoundException.
La raison en est qu’une réponse à une HEAD n’a pas de corps et qu’un appel à getInputStream jette donc une FileNotFoundException

Donc, si vous exécutez une HEAD, vous ne devriez pas essayer d’obtenir la InputStream.

0
Springrbua