1

我在 sdcard 中有一个大的 csv 文件,我想知道通过我的 android 应用程序将数据从我的 csv 文件发送到我的托管服务器的最佳方式。我的应用程序写入 csv 文件一个小时,然后在每个小时结束时运行一个服务,该服务读取这个 csv 文件并将其发送到服务器。

我最初没有向 csv 文件写入任何内容并将每个数据作为 http post 请求发送。但事实证明,我的应用显示了太多用于上传的数据使用情况。

所以我切换到将数据写入文件一个小时,并在小时结束时读取每一行并将每个元组转换为 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 回答