【问题标题】:Which is better solution get server response data?哪个更好的解决方案获取服务器响应数据?
【发布时间】:2012-11-06 08:24:49
【问题描述】:

我们通常在android开发中从服务器响应中获取数据。

/*
* get server response inputStream
*/
InputStream responseInputStream;

解决方案1:通过多次读取获取响应字符串。

      /*
       * get server response string
      */
    StringBuffer responseString = new StringBuffer();
    responseInputStream = new InputStreamReader(conn.getInputStream(),"UTF-8");

    char[] charBuffer = new char[bufferSize];
    int _postion = 0;
    while ((_postion=responseInputStream.read(charBuffer)) > -1) {
        responseString.append(charBuffer,0,_postion);
        }
    responseInputStream.close();

解决方案 2:仅读取一次响应。

String responseString = null;
int content_length=1024;
// we can get content length from response header, here assign 1024 for simple.
responseInputStream = new InputStreamReader(conn.getInputStream(),"UTF-8");

char[] charBuffer = new char[content_length];
int _postion = 0;
int position = responseInputStream.read(charBuffer)
if(position>-1){
   responseString = new String(charBuffer,0,position );
 }
responseInputStream.close();

哪种解决方案的性能更好?为什么?

注意事项:服务器响应小于1M字节的json格式数据。

【问题讨论】:

  • 第二个更快
  • 我倾向于使用第一个解决方案,因为这样我就可以确定缓冲区大小,如果您不将结果视为字符串,这通常是一个有效点。
  • @njzk2 你推荐解决方案2?
  • 第二种解决方案的一点是您不检查实际读取长度,并且您没有机制以防它未完全读取。
  • 另外,为了简单起见,有更广泛的选择,我倾向于使用 EntityUtils.toString,因为我使用的是 HttpClient。看代码,基本上是第一种解决方案(不过是捆绑的)

标签: android inputstream inputstreamreader


【解决方案1】:

为什么要重新发明轮子? ;)

如果您使用的是 HttpClient,那么只需使用 EntityUtils.toString(...)
我猜你正在使用HttpURLConnection。然后查看来自 Apache HttpClient 的 EntityUtils.toString(...) - source code。您的第一种方法与它类似。

顺便说一句,第二个代码更糟糕,因为:

new String(charBuffer,0,position ) 运行垃圾收集器

在EntityUtils中甚至在EntityUtils中:

int content_length = 1024; 在大多数情况下 8192 是套接字缓冲区的默认值,因此您的代码运行 while 循环的频率可能是它的 8 倍。

【讨论】:

    【解决方案2】:

    如果您想要显示下载/传输的数据量,我会推荐第二种方法。由于对象是作为一个整体读取的,并且由于您的 JSON 字符串的大小与 1M 相当,因此下载需要一些时间。那时,您最多可以为用户提供一条文本,说 downloading..。您无法通知用户下载量。

    但是,如果您想显示下载的数据量,请使用您提供的 first 方法。您从服务器部分读取数据的位置。您可以使用下载量更新 UI。例如 25 % 已下载...

    char[] charBuffer = new char[bufferSize];
        int _postion = 0;
        int i=0;
        while ((_postion=responseInputStream.read(charBuffer)) > -1) {
    
           //((i*buffer_size)/content_length) * 100  % completed..
    
            i++;
            }
    


    所以,我会说秒方法更好。


    顺便说一句,你考虑过这个吗?

    ObjectInputStream in = new InputStreamReader(conn.getInputStream(),"UTF-8");
    if(resposeCode==200)
    {
     String from_server=(String)  in.readObject();
    }
    

    将输入字符串作为对象读取。类实现可序列化的任何对象都可以使用ObjectOutputStream 传递并使用ObjectInputStream() 接收

    【讨论】:

    • 不管响应码。我的问题是只获取一次读取或多次读取的响应数据。
    • @boiledwater :是的,ObjectInputStream,一口气读取数据。您不必担心长度和所有内容。并且您可以传输其类实现可序列化的任何对象。响应代码不是重点。
    • 您推荐哪种解决方案?为什么?
    【解决方案3】:

    我认为第一个很好

    因为,在 First 中,它将以 char to char method 读取您的响应。

    Where , Second 将尝试读取整个响应对象或作为对象的关键字段。

    所以,据我所知,根据我的知识,第一次露营最好是第二次露营。如果有人想编辑,那将不胜感激。

    【讨论】:

    • 我不明白你说的第二个是什么意思?
    • 将尝试读取整个密钥 obj。就像在编译器中一样,直到整个程序都没有被编译,并且在逐个语句中插入语句时才会停止。得到它>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多