2016-03-29 105 views
0

我正在嘗試上傳照片並將JSON字符串傳遞給服務器。HTTPURLConnection緩衝區錯誤

我的猜測是我錯誤地計算內容長度。但我不確定我的數學問題在哪裏。

任何人都可以幫我追查我的錯誤嗎?

我收到以下錯誤:

E/PhotoUpload: error: expected 14591 bytes but received 15183 java.net.ProtocolException: expected 14591 bytes but received 15183 at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:311) at com.android.okio.RealBufferedSink.flush(RealBufferedSink.java:154) at com.android.okio.RealBufferedSink$1.flush(RealBufferedSink.java:137) at java.io.FilterOutputStream.flush(FilterOutputStream.java:88) at java.io.DataOutputStream.flush(DataOutputStream.java:63) at com.mycompany.myapp.TakePhotoActivity$BGUploadImage.doInBackground(TakePhotoActivity.java:381) at com.mycompany.myapp.TakePhotoActivity$BGUploadImage.doInBackground(TakePhotoActivity.java:273)

E/PhotoUpload: error: expected 14591 bytes but received 15183 java.net.ProtocolException: expected 14591 bytes but received 15183 at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:311) at com.android.okio.RealBufferedSink.flush(RealBufferedSink.java:154) at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:769) at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:405) at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:349) at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:203) at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210) at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25) at com.mycompany.myapp.TakePhotoActivity$BGUploadImage.doInBackground(TakePhotoActivity.java:393) at com.mycompany.myapp.TakePhotoActivity$BGUploadImage.doInBackground(TakePhotoActivity.java:273) at android.os.AsyncTask$2.call(AsyncTask.java:292)

public class BGUploadImage extends AsyncTask<String, Integer, Integer> { 
     int maxBufferSize = 1 * 256 * 1024; 
     int headerSize = 89; 
     String urlString = "http://www.mywebsite.com/someapi"; 
     int fileSize = 0; 
     int infoSize = 0; 
     private int i; 


     @Override 
     protected void onPreExecute() { 
     } 

     @Override 
     protected void onProgressUpdate(Integer... values) { 
     } 

     @Override 
     protected Integer doInBackground(String... file) { 

      Integer ret = 0; 

      HttpURLConnection conn = null; 
      DataOutputStream dos = null; 
      DataInputStream inStream = null; 

      String exsistingFileName = file[0]; 

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

      String json = JSONCalls.uploadImageJSON(thisCallKey); 

      int bytesRead, bytesAvailable, bufferSize; 
      byte[] buffer; 

      try { 
       Log.i("PhotoUpload", "Start uploading file: " + file[0]); 

       FileInputStream fileInputStream = new FileInputStream(new File(exsistingFileName)); 

       URL url = new URL(urlString); 

       conn = (HttpURLConnection) url.openConnection(); 
       conn.setDoInput(true); 
       conn.setDoOutput(true); 
       conn.setUseCaches(false); 

       fileSize = fileInputStream.available(); 
       infoSize = fileSize + headerSize + file[0].length(); 
       conn.setFixedLengthStreamingMode(infoSize); 
       conn.setRequestMethod("POST"); 
       conn.setRequestProperty("Connection", "Keep-Alive"); 
       conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 

       dos = new DataOutputStream(conn.getOutputStream()); 

       //JSON PART 
       dos.writeBytes(twoHyphens + boundary + lineEnd); 
       dos.writeBytes("Content-Disposition: form-data; name='params'" + lineEnd); 
       dos.writeBytes(json); 
       dos.writeBytes(lineEnd); 

       //MEDIA PART 
       dos.writeBytes(twoHyphens + boundary + lineEnd); 
       dos.writeBytes("Content-Disposition: form-data; name = 'UploadedFile'; filename = '" + file[0] + "' " + lineEnd); 
       dos.writeBytes(lineEnd); 

       // create a buffer of maximum size 
       bytesAvailable = fileInputStream.available(); 
       bufferSize = Math.min(bytesAvailable, maxBufferSize); 
       buffer = new byte[bufferSize]; 

       // read file and write it into form... 
       bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

       int bytesSent = 0; 
       while (bytesRead > 0) { 
        if (bytesSent > 0) { 
         int pg = (bytesSent * 100)/infoSize; 
         publishProgress(pg); 
        } 
        bytesSent += bufferSize; 
        dos.write(buffer, 0, bufferSize); 
        bytesAvailable = fileInputStream.available(); 
        bufferSize = Math.min(bytesAvailable, maxBufferSize); 
        bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
       } 

       // send multipart form data necesssary after file data... 
       dos.writeBytes(lineEnd); 
       dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 

       //close streams 
       fileInputStream.close(); 
       dos.flush(); 
       dos.close(); 

      } catch (MalformedURLException ex) { 
       Log.e("PhotoUpload", "error: " + ex.getMessage(), ex); 
       ret = 1; 
      } catch (IOException ioe) { 
       Log.e("PhotoUpload", "error: " + ioe.getMessage(), ioe); 
       ret = 1; 
      } 

      try { 
       inStream = new DataInputStream(conn.getInputStream()); 
       String str; 

       while ((str = inStream.readLine()) != null) { 
        Log.i("PhotoUpload", "Server Response" + str); 
       } 
       inStream.close(); 
      } catch (IOException ioex) { 
       Log.e("PhotoUpload", "error: " + ioex.getMessage(), ioex); 
       ret = 1; 
      } 

      return ret; 
     } 

     @Override 
     protected void onPostExecute(Integer r) { 

     } 

    } 
} 
+0

你無處計算內容的長度。你也不是一個人。但是你也不必這樣做。 – greenapps

+0

從您的日誌:'TakePhotoActivity.java:381'。該行上有哪些代碼? – greenapps

+0

濫用'available()'。看到Javadoc。它警告你到底在做什麼。 – EJP

回答

0

My guess is I am incorrectly calculating the content-length.

如你不計算內容長度可言,或發送它,它是很難理解這是什麼猜測可能可能是基於。

但是,您的代碼還存在其他問題。您的副本循環:

// read file and write it into form... 
bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
int bytesSent = 0; 
while (bytesRead > 0) { 
    if (bytesSent > 0) { 
     int pg = (bytesSent * 100)/infoSize; 
     publishProgress(pg); 
    } 
    bytesSent += bufferSize; 
    dos.write(buffer, 0, bufferSize); 
    bytesAvailable = fileInputStream.available(); 
    bufferSize = Math.min(bytesAvailable, maxBufferSize); 
    bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
} 

是一個邪惡的混亂。 Java複製循環不會比這更復雜:

byte[] buffer = new byte[8192]; 
int count; 
while ((count = in.read(buffer)) > 0) 
{ 
    out,write(buffer, 0, count); 
} 

您不需要與文件大小相同的緩衝區。這只是在浪費空間。並且使用available()作爲衡量文件大小,或者爲它分配足夠大的緩衝區,在Javadoc中特別警告。這不是它的目的。 available()的正確用途很少,這不是其中之一。

flush()之前close()是多餘的。