2012-03-12 12 views
0

マイアップロードコード:アップロードファイル

String end = "\r\n"; 
String twoHyphens = "--"; 
String boundary = "*****"; 
try { 
URL url = new URL(ActionUrl); 
HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
con.setDoInput(true); 
con.setDoOutput(true); 
con.setUseCaches(false); 
con.setRequestMethod("POST"); 
con.setRequestProperty("Connection", "Keep-Alive"); 
con.setRequestProperty("Accept", "text/*"); 
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
DataOutputStream ds = new DataOutputStream(con.getOutputStream()); 
ds.writeBytes(twoHyphens + boundary + end); 
ds.writeBytes("Content-Disposition: form-data;" + "name=\"folder\"" + end + end); 
ds.write(SavePath.getBytes("UTF-8")); 
ds.writeBytes(end); 
ds.writeBytes(twoHyphens + boundary + end); 
ds.writeBytes("Content-Disposition: form-data;" + "name=\"Filedata\"; filename=\""); 
ds.write(FileName.getBytes("UTF-8")); 
ds.writeBytes("\"" + end); 
ds.writeBytes(end); 
FileInputStream fStream = new FileInputStream(uploadFilepath+""+FileName); 
int bufferSize = 1024; 
byte[] buffer = new byte[bufferSize]; 
int length = -1; 
int pro = 0; 
while((length = fStream.read(buffer)) != -1) { 
ds.write(buffer, 0, length); 
}  
ds.writeBytes(end); 
ds.writeBytes(twoHyphens + boundary + twoHyphens + end); 
fStream.close(); 
ds.flush(); 
InputStream is = con.getInputStream(); 
int ch; 
StringBuffer b = new StringBuffer(); 
while((ch = is.read()) != -1) { 
b.append((char)ch); 
} 
ds.close(); 
} 
catch(Exception e) { 
e.printStackTrace(); 
} 

小さなファイルをアップロードしながら、それが動作することができます。 しかし、16MB以上になるとアップロードが失敗し、OutOfMemoryエラーが表示されます。 バッファ内にすべてのデータを置くことが原因だと思います。 バッファを1024バイト保存しながらデータを送信するようにしたいと思います。 しかし、私はそれをする考えはありません。 誰かが私にそれを手伝ってもらえますか?

+0

あなたは(ds.flushを追加してみてください可能性があり)。 while((length = fStream.read(buffer))!= -1){ ds.write(バッファ、0、長さ);サーバーにすべてのデータをフラッシュすることができるようにします(サーバーがds.writeBytes(twoHyphens + boundary + twoHyphens + end);まで呼び出されるまで待つと仮定しています) –

+0

私は試してみました。それでも、同じ行で同じエラーが発生します。 – brian

答えて

1

エラーの発生場所を確認してください。私はそれが応答を読んでいる間だと思う。この場合、サーバーがStringBufferに配置した多くのデータで応答しているようです。あなたは実際に応答全体を消費し、それを記憶しておく必要がありますか?それがファイルの場合は、メモリに保存するのではなく保存します。


私はもう少し研究をしましたが、もう1つの可能性があります。デフォルトでAndroid JVMの最大ヒープは16MBです。詳細については、thisを参照してください。

一方、サーバーが実際にデータを消費しない場合、ほとんどのデータはクライアントに格納されます。したがって、データの最大ヒープを超えると、クライアントは失敗します。

あなたのサーバーがストリームからデータを読み取っていないと思われます。

次のクラス(コードの関連部分のスニペット)は、この問題を示しています。任意のJVM上で次のように実行します。

java -Xmx16m -cp . Test 

これは非常に迅速にOOMを生成します。実際、予想よりはるかに早い。

import java.io.*; 
import java.net.*; 

public class Test { 
    public static void main(String argv[]) throws Exception { 
    new Thread() { 
     public void run() { 
     try { 
      new ServerSocket(12000).accept(); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
     } 
    }.start(); 

    URL url = new URL("http://localhost:12000/"); 
    HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
    con.setDoInput(true); 
    con.setDoOutput(true); 
    con.setUseCaches(false); 
    DataOutputStream ds = new DataOutputStream(con.getOutputStream()); 
    int bufferSize = 1024; 
    byte[] buffer = new byte[bufferSize]; 
    for (int i=0;i<100000;i++) { 
     ds.write(buffer, 0, 1024); 
     System.out.println("Written chunk " + i); 
    }  
    ds.flush(); 
    } 
} 
+0

ds.write(buffer、0、length)行で発生します。 in whileループ。 – brian

+0

その部分では、1024バイトのバッファ以外は何もメモリに保持しません。それは 'DataOutputSteram'で何かすることができます。私は' OutputStream'に直接書き込みを試み、何が起こるかを見ます。 –

+0

私はcon.setFixedLengthStreamingMode(1024);も試してみてください。エラー "java.io.IOException:expected 865 bytes but received 1024"が表示されました。 – brian

2

ブライアン・サーバーは、チャンクモードをサポート、または

con.setFixedLengthStreamingMode(packet_size); 

​​を追加することができれば、あなたは

DataOutputStream ds = new DataOutputStream(con.getOutputStream()); 

con.setChunkedStreamingMode(0); 

を追加する必要があります。

2

UPLOADの100MBのファイル

パブリック文字列sendFileToServer(文字列のファイル名、文字列のTargetURL){

String response = "error"; 
Log.e("Image filename", filename); 
Log.e("url", targetUrl); 
HttpURLConnection connection = null; 
DataOutputStream outputStream = null; 
// DataInputStream inputStream = null; 

String pathToOurFile = filename; 
String urlServer = targetUrl; 
String lineEnd = "\r\n"; 
String twoHyphens = "--"; 
String boundary = "*****"; 
DateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH:mm:ss"); 

int bytesRead, bytesAvailable, bufferSize; 
byte[] buffer; 
int maxBufferSize = 1 * 1024; 
try { 
    FileInputStream fileInputStream = new FileInputStream(new File(
      pathToOurFile)); 

    URL url = new URL(urlServer); 
    connection = (HttpURLConnection) url.openConnection(); 

    // Allow Inputs & Outputs 
    connection.setDoInput(true); 
    connection.setDoOutput(true); 
    connection.setUseCaches(false); 
    connection.setChunkedStreamingMode(1024); 
    // Enable POST method 
    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); 

    String connstr = null; 
    connstr = "Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" 
      + pathToOurFile + "\"" + lineEnd; 
    Log.i("Connstr", connstr); 

    outputStream.writeBytes(connstr); 
    outputStream.writeBytes(lineEnd); 

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

    // Read file 
    bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
    Log.e("Image length", bytesAvailable + ""); 
    try { 
     while (bytesRead > 0) { 
      try { 
       outputStream.write(buffer, 0, bufferSize); 
      } catch (OutOfMemoryError e) { 
       e.printStackTrace(); 
       response = "outofmemoryerror"; 
       return response; 
      } 
      bytesAvailable = fileInputStream.available(); 
      bufferSize = Math.min(bytesAvailable, maxBufferSize); 
      bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     response = "error"; 
     return response; 
    } 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(twoHyphens + boundary + twoHyphens 
      + lineEnd); 

    // Responses from the server (code and message) 
    int serverResponseCode = connection.getResponseCode(); 
    String serverResponseMessage = connection.getResponseMessage(); 
    Log.i("Server Response Code ", "" + serverResponseCode); 
    Log.i("Server Response Message", serverResponseMessage); 

    if (serverResponseCode == 200) { 
     response = "true"; 
    } 

    String CDate = null; 
    Date serverTime = new Date(connection.getDate()); 
    try { 
     CDate = df.format(serverTime); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e("Date Exception", e.getMessage() + " Parse Exception"); 
    } 
    Log.i("Server Response Time", CDate + ""); 

    filename = CDate 
      + filename.substring(filename.lastIndexOf("."), 
        filename.length()); 
    Log.i("File Name in Server : ", filename); 

    fileInputStream.close(); 
    outputStream.flush(); 
    outputStream.close(); 
    outputStream = null; 
} catch (Exception ex) { 
    // Exception handling 
    response = "error"; 
    Log.e("Send file Exception", ex.getMessage() + ""); 
    ex.printStackTrace(); 
} 
return response; 

}

関連する問題