2014-10-29 85 views
0

我讓我的Android應用程序這個HTTP POST請求:圖像/視頻/音頻輸入上傳成功從安卓到PHP,但不能打開它們 - 破損/損壞

private final String delimiter = "--"; 
    private final String boundary = "SwA" 
      + Long.toString(System.currentTimeMillis()) + "SwA"; 
    private final String charset = "UTF-8"; 
    private final String lineSpace = "\r\n"; 
    private final String domain = (domain); 

    private HttpURLConnection configureConnectionForMultipart(String url) 
      throws MalformedURLException, IOException { 
     HttpURLConnection con = (HttpURLConnection) (new URL(url)) 
       .openConnection(); 
     con.setRequestMethod("POST"); 
     con.setDoInput(true); 
     con.setDoOutput(true); 
     con.setRequestProperty("Connection", "Keep-Alive"); 
     con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" 
       + boundary); 
     return con; 
    } 

    private void addFormPart(String paramName, String value, DataOutputStream os) 
      throws IOException { 
     os.writeBytes(lineSpace + delimiter + boundary + lineSpace); 
     os.writeBytes("Content-Disposition: form-data; name=\"" + paramName 
       + "\"" + lineSpace); 
     os.writeBytes("Content-Type: text/plain; charset=" + charset 
       + lineSpace); 
     os.writeBytes(lineSpace + value + lineSpace); 
     os.flush(); 
    } 

    private void addFilePart(String paramName, File data, DataOutputStream os) 
      throws IOException { 
     os.writeBytes(lineSpace + delimiter + boundary + lineSpace); 
     os.writeBytes("Content-Disposition: form-data; name=\"" + paramName 
       + "\"; filename=\"" + data.getAbsolutePath() + "\"" + lineSpace); 
     os.writeBytes("Content-Type: application/octet \r\n"); 
     os.writeBytes("Content-Transfer-Encoding: binary" + lineSpace); 
     // os.writeBytes(lineSpace); 
     os.flush(); 

     FileInputStream fis = new FileInputStream(data); 
     byte[] buffer = new byte[4096]; 
     int bytesRead = -1; 
     while ((bytesRead = fis.read(buffer)) != -1) { 
      os.write(buffer, 0, bytesRead); 
     } 
     os.writeBytes(lineSpace); 
     os.flush(); 
     fis.close(); 
    } 

    private void finishMultipart(DataOutputStream os) throws IOException { 
     // os.writeBytes(lineSpace); 
     os.flush(); 
     os.writeBytes(delimiter + boundary + delimiter + lineSpace); 
     os.close(); 
    } 

private class ObjectUploadRunnable implements Runnable { 

     private final String _filePath; 
     private final String _url = domain + "upload.php"; 

     public ObjectUploadRunnable(String filePath) { 
      _filePath = filePath; 
     } 

     @Override 
     public void run() { 

      try { 
       HttpURLConnection con = configureConnectionForMultipart(_url); 
       con.connect(); 
       DataOutputStream os = new DataOutputStream(
         con.getOutputStream()); 
       File data = new File(_filePath); 
       addFilePart("data", data, os); 
       finishMultipart(os); 
       String response = getResponse(con); 
       Log.i("BoxUpload", response); 
       con.disconnect(); 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

我抓住它我的服務器上腳本upload.php的:

... 
$dir = "/uploads/"; 
$target_path = $dir.basename($_FILES['data']['name']); 

if (move_uploaded_file($_FILES['data']['tmp_name'], $target_path)) { 
    echo "file uploaded"; 
} else { 
    echo print_r(error_get_last()); 
} 

一切似乎都成功,在與正確大小的文件被上傳到我的服務器,在所需的目錄。但是,當我嘗試打開文件時,它似乎以某種方式損壞或損壞,因爲它不會在我嘗試的任何應用程序中打開。我上傳圖片= jpeg,視頻= mp4,音頻= mp4。上傳前,這些文件都在客戶端上運行。我是否錯過了在POST請求中正確編碼文件的內容?我從來沒有做過文件上傳過,所以我會很感激一些建議......

編輯

在這種情況下是相關的,我發現我已經上傳的文件已經長大由〜100kb。也許有東西被添加到我的二進制數據,這是腐敗的文件?

+0

你只是假設上傳永遠不會失敗。餿主意。 **在做任何事情之前,總是**檢查$ _FILES中的'['errors']'參數。 – 2014-10-29 20:45:34

+0

好的,我做了一個var_dump [$ _ FILES),錯誤字段顯示0錯誤。這足夠嗎?我認爲實際上傳中沒有任何錯誤,因爲正確尺寸的文件已上傳到我打算推出的位置。我無法打開它。 – ethan123 2014-10-29 20:56:54

回答

0

這裏想通了這個問題。我在addFilePart中註釋到的額外行實際上是必需的。我想在這部分請求中需要兩行標題信息和二進制數據。要清楚,它應該看起來像:

private void addFilePart(String paramName, File data, DataOutputStream os) 
     throws IOException { 
    os.writeBytes(lineSpace + delimiter + boundary + lineSpace); 
    os.writeBytes("Content-Disposition: form-data; name=\"" + paramName 
      + "\"; filename=\"" + data.getAbsolutePath() + "\"" + lineSpace); 
    os.writeBytes("Content-Type: application/octet \r\n"); 
    os.writeBytes("Content-Transfer-Encoding: binary" + lineSpace); 
    os.writeBytes(lineSpace); 
    os.flush(); 

    FileInputStream fis = new FileInputStream(data); 
    byte[] buffer = new byte[4096]; 
    int bytesRead = -1; 
    while ((bytesRead = fis.read(buffer)) != -1) { 
     os.write(buffer, 0, bytesRead); 
    } 
    os.writeBytes(lineSpace); 
    os.flush(); 
    fis.close(); 
} 

現在一切正常!