【问题标题】:StringBuilder lost data when convert to StringStringBuilder 转换为 String 时丢失数据
【发布时间】:2014-07-13 14:07:09
【问题描述】:

这是什么问题

当我尝试从我的 StringBuilder 获取字符串时遇到问题

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()), 128 * 1024);
StringBuilder dataResponseSB = new StringBuilder();
String line ;
while ((line = reader.readLine()) != null) {
    dataResponseSB.append(line);
    if (DataFactory.DEBUG_MODE) {
        // all data here are complete
        Log.i("===LoadDataActivity","line: "+line);
    }
}
String rawdata = new String(dataResponseSB); // dataResponseSB.toString(); also not work
if (DataFactory.DEBUG_MODE) {
    // data here are lost
    Log.i("===LoadDataActivity","rawdata: "+rawdata);
}

(-) 我从 BufferedReader .readLine() 收到大量数据

(-) 我使用 Log 检查并确保每行大约有 5 行 8000 缓冲区大小我非常确定我已正确接收所有数据

(1) 我将每一行附加到 StringBuilder Here

(-) 在我将所有行附加到 StringBuilder 之后

(2) 我尝试将其转换回字符串

(-) 现在,问题来了,当我在这里检查新字符串时,数据只有 8192(它应该至少包含 30,000 或更多)

有什么问题?我不确定它在附加到 StringBuilder(1) 时会丢失,或者在转换回 String (2) 时会丢失


我在这里添加了我在下面尝试过的代码,我尝试了 UTF8 和没有 UTF8

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            //params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, );
            params.setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 128 * 1024);
            HttpClient client = new DefaultHttpClient(params);


        //  HttpClient client = new DefaultHttpClient(new BasicHttpParams());
            HttpPost httppost = new HttpPost(DataFactory.REQUEST_API_URL + "?id=" + DataFactory.USER_ID );
            // Depends on your web service

            HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
            HttpConnectionParams.setSocketBufferSize(client.getParams(), 128 * 1024);
            HttpResponse response = client.execute(httppost);  
            //response.setParams(client.getParams().setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 128 * 1024));

            //String rawdata = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
           // String rawdata = EntityUtils.toString(response.getEntity());
            String rawdata = getResponseBody(response.getEntity());

            //Scanner s = new Scanner(response.getEntity().getContent()).useDelimiter("\\A");
            //String rawdata = s.hasNext() ? s.next() : "";


            /*

            //BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            // ===================

            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()), 128 * 1024);
            StringBuilder dataResponseSB = new StringBuilder();
            String line ;
            while ((line = reader.readLine()) != null) {
                dataResponseSB.append(line);
                if (DataFactory.DEBUG_MODE) {
                    Log.i("===LoadDataActivity","line: "+line);
                }
            }
            dataResponseSB.trimToSize();
            String rawdata = new String(dataResponseSB);

            /*
            InputStreamReader reader = new InputStreamReader(response.getEntity().getContent());
            StringBuffer sb = new StringBuffer();
            int c;
            while ((c = reader.read()) != -1) {
                sb.append((char)c);
                if (DataFactory.DEBUG_MODE) {
                    //Log.i("===LoadDataActivity","line: "+line);
                }
            }
            */

【问题讨论】:

  • 使用String json = EntityUtils.toString(response.getEntity())
  • 您是否尝试插入打印/日志语句来测试您的猜测?
  • @Raghunandan 尝试了 EntityUtils.toString 和 IOUtils.toString
  • @Raghunandan 对不起,你的代码也是正确的,因为我很笨

标签: java android string stringbuilder


【解决方案1】:

我很确定这是问题所在:

Log.i("===LoadDataActivity","rawdata: "+rawdata);

您假设一个日志条目可以包含您的所有数据 - 我相信每个日志条目限制为 8192 个字符。

我建议您记录 rawdata.length(),您会发现它实际上已获取所有数据 - 只是记录失败。

【讨论】:

  • 非常感谢,这是我的代码的实际问题,而不是这个,我发现我得到的 beffered 长度增加了 1 (some thing lime 40,000 + 1) ,不知道是什么错了
  • 最佳做法是这样做:Log.i("===LoadDataActivity","rawdata: ["+rawdata + "]");(注意数据周围的括号)。这样,很明显不是原始数据被截断,StringBuilder 将是“无辜的”。
【解决方案2】:

试试这个,

public String getResponseBody(final HttpEntity entity) throws IOException, ParseException {

        if (entity == null) {
            throw new IllegalArgumentException("HTTP entity may not be null");
        }

        InputStream instream = entity.getContent();

        if (instream == null) {
            return "";
        }

        if (entity.getContentLength() > Integer.MAX_VALUE) {
            throw new IllegalArgumentException(

                    "HTTP entity too large to be buffered in memory");
        }

        StringBuilder buffer = new StringBuilder();

        BufferedReader reader = new BufferedReader(new InputStreamReader(instream, HTTP.UTF_8));

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

        } finally {
            instream.close();
            reader.close();
        }
        System.out.println("GEN END : " + Calendar.getInstance().getTimeInMillis());
        return buffer.toString();

    }

【讨论】:

  • 我复制/粘贴您的代码并在其中使用结果仍然只显示 8192 谢谢,
  • 对不起,你的代码也是正确的,因为我太笨了
【解决方案3】:
// Try this way,hope this will help you to solve your problem...

StringBuilder buffer = new StringBuilder();

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), HTTP.UTF_8));

String line = null;
try {
    while ((line = reader.readLine()) != null) {
            buffer.append(line);
    }

} finally {
    instream.close();
    reader.close();
}
System.out.println("Buffer : " + buffer.toString());

【讨论】:

  • 我复制/粘贴您的代码并在其中使用结果仍然只显示 8192 谢谢
  • 对不起,你的代码也是正确的,因为我太笨了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2017-08-09
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
相关资源
最近更新 更多