0

I have Android application that periodically uploads some files to web server.

The problem is that sometimes file is uploaded successfully (and I am getting some response from server), but sometimes I am getting FileNotFoundException at line inputStream = connection.getInputStream();. As I lnow it means that file theoretically was uploaded to server but we could not get stream that should give us response.

Please advice me some solution to avoid this exception. Server is IIS, it works perfectly, connection is stable.

My code:

public class UploadFileAsync extends AsyncTask<String, String, String> {
private final Callback<String> callback;
private HttpURLConnection connection = null;
private DataOutputStream outputStream = null;
private FileInputStream fileInputStream = null;
private InputStream inputStream = null;

public UploadFileAsync(Callback<String> callback) {
    this.callback = callback;
}

@Override
protected String doInBackground(String... args) {
    String fileURI = args[0];
    String filePath = args[1];

    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";

    String result = null;

    try {
        String fileName = new File(filePath).getName();
        fileInputStream = new FileInputStream(filePath);

        URL connectURL = new URL(fileURI);
        connection = (HttpURLConnection) connectURL.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

        outputStream = new DataOutputStream(connection.getOutputStream());

        outputStream.writeBytes(twoHyphens + boundary + lineEnd);
        outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + fileName + "\"" + lineEnd);
        outputStream.writeBytes(lineEnd);

        int bytesAvailable = fileInputStream.available();
        int maxBufferSize = 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        while (bytesRead > 0) {
            outputStream.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }
        outputStream.writeBytes(lineEnd);
        outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
        outputStream.flush();

        inputStream = connection.getInputStream();

        int ch;
        StringBuffer stringBuffer = new StringBuffer();
        while ((ch = inputStream.read()) != -1) {
            stringBuffer.append((char) ch);
        }

        result = stringBuffer.toString();
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("APP_TAG", "UploadFileAsync. URL: " + fileURI + " Upload FAIL.");
        result = e.getMessage();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (Exception e) {
            }
        }
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (Exception e) {
            }
        }
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (Exception e) {
            }
        }
    }
    return result;
}

@Override
public void onPostExecute(String result) {
    if (callback != null) {
        callback.process(result);
    }
}

}

Exception stacktrace:

java.io.FileNotFoundException: http://myserver.com/files 
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) 
at myapp.core.utils.network.UploadFileAsync.doInBackground(UploadFileAsync.java:90) 
at myapp.core.utils.network.UploadFileAsync.doInBackground(UploadFileAsync.java:17) 
at android.os.AsyncTask$2.call(AsyncTask.java:287) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
at java.lang.Thread.run(Thread.java:856)
yuralife
  • 1,545
  • 2
  • 21
  • 35
  • Hi. From the doc, getInputStream() only throws IOException, not FileNotFoundException (http://developer.android.com/reference/java/net/URLConnection.html#getInputStream%28%29). Are you sure that the error occures here. Also, do you have access to the server's code. maybe the error is on the server's side – Basile Perrenoud Dec 17 '13 at 10:41
  • Server side was double checked. And it works perfectly (by Fiddler tests). So I propose that it is just on android side. Android version 4.1.1. – yuralife Dec 17 '13 at 10:54
  • You could try to print connection.getResponseCode. If might contains an error code. You can also try to call Thread.sleep(500) after sending your file: maybe the server hasn't had enough time to properly store your file, so waiting a short while (maybe even less than 500ms) could solve your problem – Basile Perrenoud Dec 17 '13 at 13:20
  • I tried even Thread.sleep(1000), but that didn`t help. – yuralife Dec 17 '13 at 14:25
  • Ok, do you have something in connection.getResponseCode() ? – Basile Perrenoud Dec 17 '13 at 15:31
  • Yes, I have "500 Internal Server Error" including response message. – yuralife Dec 17 '13 at 15:34
  • 500 Internal Server Error usually means that the error is on the server side. You can try to read from the inputstream you get using connection.getErrorStream(). The server might be sending some more info here. – Basile Perrenoud Dec 17 '13 at 15:48

1 Answers1

0

I had the same problem and I resolved it. The problem is caused by timeout. The only thing we can do is to modify web.config as following.

<configuration>
    <system.web>
         <httpRuntime targetFramework="4.5.2" maxRequestLength="10240" executionTimeout="300" />
    </system.web>
</configuration>
George
  • 61
  • 1
  • 3