1

SDカードに大きなcsvファイルがあり、Androidアプリを介してcsvファイルからホストされたサーバーにデータを送信する最良の方法を知りたいです。私のアプリはcsvファイルに1時間書き込み、毎時間の終わりにこのcsvファイルを読み取ってサーバーに送信するサービスを実行します。

最初はcsvファイルに何も書き込まず、各データをhttpポストリクエストとして送信していました。しかし、私のアプリがアップロードするにはデータ使用量が多すぎることが判明しました。

そこで、データをファイルに1時間書き込むことに切り替え、1時間の終わりに各行を読み取り、各タプルをjsonオブジェクトに変換し、それをjson配列に入れ、その配列を名前と値のペアを介してjsonオブジェクトとして送信しました.

問題 1:

CSV ファイルが大きすぎるため、配列に 2000 個を超える json オブジェクトを追加してこのように送信しようとすると、メモリ不足の例外が発生します (** でマークされた行で問題が発生します)

nameValuePairs.add(new BasicNameValuePair("myjson", json_array_obj.toString()));

Thread server = new Thread(){
    String line = null;
    public void run()
    {
        try{

            HttpClient httpclient1 = new DefaultHttpClient();
            HttpPost httppost1 = new HttpPost("http://www.example.com/filename.php");


            **httppost1.setEntity(new UrlEncodedFormEntity(nameValuePairs));**
            HttpResponse httpResponse = httpclient1.execute(httppost1);

            HttpEntity httpEntity = httpResponse.getEntity();
            line = EntityUtils.toString(httpEntity);

            Log.e("line" , line);
          }
          catch(Exception e)
          {
            Log.v("catch", "executed");
          } 

    }
};
server.start();

Logcatが示した:

`12-28 13:01:18.828: E/AndroidRuntime(2690FATAL EXCEPTION: Thread-16132
 12-28 13:01:18.828: E/AndroidRuntime(26908): java.lang.OutOfMemoryError
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at java.lang.StringBuilder.append(StringBuilder.java:216)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at libcore.net.UriCodec.appendHex(UriCodec.java:212)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at libcore.net.UriCodec.appendHex(UriCodec.java:206)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at libcore.net.UriCodec.appendEncoded(UriCodec.java:109)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at libcore.net.UriCodec.encode(UriCodec.java:133)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at java.net.URLEncoder.encode(URLEncoder.java:57)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at org.apache.http.client.utils.URLEncodedUtils.encode(URLEncodedUtils.java:184)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at org.apache.http.client.utils.URLEncodedUtils.format(URLEncodedUtils.java:163)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at org.apache.http.client.entity.UrlEncodedFormEntity.<init>(UrlEncodedFormEntity.java:71)
 12-28 13:01:18.828: E/AndroidRuntime(26908):   at com.example.acgylo.CSVtoServer$1.run(CSVtoServer.java:168)8): `

その後、メモリ オーバーフローが発生するため、多数のオブジェクトを含む json 配列を namevaluepair として送信できないことがわかりました。

だから私はこれを行うための最良の方法は何かを知りたい:

オプション 1 : 500 のバッチでデータを送信します (つまり、500 行の csv をまとめて)。

Android で HTTP 経由で CSV から 2k タプル (またはそれ以上) を送信する効率的な方法はありますか?

問題 2:

a) Android アプリケーションのデータ使用量を減らす方法を知りたいですか?

b) データの使用量が少ないもの:

One http request with large json object sent as string OR Multiple http requests with smaller json objects?

上記の問題に対する効率的な解決策を見つけるのを手伝ってください。どんな助けでも大歓迎です。

前もって感謝します。

4

2 に答える 2

2

ストリーミングはここでの魔法の言葉です。すべてのデータをメモリに読み取ってから送信する代わりに、レコードごとにそれを行うことができます。

  1. HTTP post 接続を開く
  2. 冒頭「[」を書く
  3. CSV ファイルからレコードを読み取り、JSON に変換します
  4. JSON 文字列を回線経由で送信する
  5. JSON 配列内のオブジェクトを区切る「,」を送信します
  6. すべてのデータが送信されるまで、手順 3 ~ 5 を繰り返します (最後のレコードの後の「,」は省略します)。
  7. 配列の末尾に「]」を送信
  8. HTTP リクエストを終了する
于 2012-12-28T19:09:18.673 に答える
0

あなたがモバイルデバイスからサーバーに大量のデータを送信している場合、あなたが言ったように、あなたはどちらかをすることができます

a)データを細かく分割し、機能する可能性のある部分間に依存関係がない場合

また

b)データをzipファイルに圧縮し、サーバーに送信するだけです。ほとんどの場合、zipファイルを受け入れるようにサーバーを変更してから通常の処理を行う方がおそらく簡単です。

于 2013-01-11T15:42:16.803 に答える