如何以块的形式获取 JSON 数据来报告进度?

发布于 2024-11-23 15:07:57 字数 1445 浏览 0 评论 0原文

我需要通过 REST API 下载联系人数据,该数据采用 JSON 格式。问题是,可能有很多联系人,所以我想观察进度(已经下载了多少联系人)并向用户报告(带有进度条,下面的代码在线程中运行)。

但是,似乎 client.execute(getRequest); 行建立连接并一次性下载整个内容,即我的InputStream阅读器(以块的形式获取内容)似乎毫无用处。现在我想知道如何让它分块工作,以便我可以报告进度?

/** prepare HTML get request */
HttpGet getRequest = new HttpGet(url[0]);
getRequest.addHeader("Authorization", "OAuth " + myTokens.get_access_token());

/** execute HTML request */
DefaultHttpClient client = new DefaultHttpClient();
JSONArray records = null;
HttpResponse response = client.execute(getRequest);

/** init response handlers for input stream */
InputStream input = new BufferedInputStream(response.getEntity().getContent());

byte data[] = new byte[MAX_BUFFER_SIZE];

long totalContactsCount = -1;
int readContactsCount = 0;
int currentByteReadCount = 0;

/** read response from inpus stream */
while ((currentByteReadCount = input.read(data)) != -1) {
    String readData = new String(data, 0, currentByteReadCount);
    dataString.append(readData);

    // then +1 progress on every ...},{... (JSON object separator)
    if (readData.indexOf("},{") >= 0) {
        readContactsCount++;
    }

    // publishing the progress....
    if (totalContactsCount > 0) {
        publishProgress((int)(readContactsCount * 100 / totalContactsCount));
    }
}
input.close();

/** transform response into JSONArray */
String result = dataString.toString();

//... convert into JSONArray

I need to download contact data via a REST API, which I get in JSON format. Issue is, it might be many many contacts, so I want to observe the progress (how many contacts have already been downloaded) and report back to the user (with a progress bar, the code below runs in a thread).

However, it seems that the line client.execute(getRequest); establishes the connection and downloads the whole content in one go, i.e. my InputStream reader (to fetch the content in chunks) seems to be useless. Now I'm wondering how to make it work in chunks, so I can report on the progress?

/** prepare HTML get request */
HttpGet getRequest = new HttpGet(url[0]);
getRequest.addHeader("Authorization", "OAuth " + myTokens.get_access_token());

/** execute HTML request */
DefaultHttpClient client = new DefaultHttpClient();
JSONArray records = null;
HttpResponse response = client.execute(getRequest);

/** init response handlers for input stream */
InputStream input = new BufferedInputStream(response.getEntity().getContent());

byte data[] = new byte[MAX_BUFFER_SIZE];

long totalContactsCount = -1;
int readContactsCount = 0;
int currentByteReadCount = 0;

/** read response from inpus stream */
while ((currentByteReadCount = input.read(data)) != -1) {
    String readData = new String(data, 0, currentByteReadCount);
    dataString.append(readData);

    // then +1 progress on every ...},{... (JSON object separator)
    if (readData.indexOf("},{") >= 0) {
        readContactsCount++;
    }

    // publishing the progress....
    if (totalContactsCount > 0) {
        publishProgress((int)(readContactsCount * 100 / totalContactsCount));
    }
}
input.close();

/** transform response into JSONArray */
String result = dataString.toString();

//... convert into JSONArray

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

避讳 2024-11-30 15:07:57

不幸的是,从 DefaultHttpClient 的文档中可以看出,execute 方法返回一个已解析的 HTTP 响应,因此已从网络读取,因此您无法插入输入流。该流已准备好供您阅读,但正如您所注意到的,一旦它被检索。你必须使用另一种策略。例如,尝试使用套接字 API 进行连接。

Unfortunatelly, as it seems from the documentation on DefaultHttpClient, the execute method returns a HTTP response, already parsed, and hence, already read from the network, so you cannot plug in the input stream. That stream is prepared for you to be read, but once it has been retreived, as you have noticed. You'd have to use another strategy. For example, trying yourself the connection using the sockets API.

驱逐舰岛风号 2024-11-30 15:07:57

您可以首先向 Web 服务询问其拥有的联系人总数(例如 100,000),然后向其询问联系人的各个“页面”(例如 100 个联系人/页面)。当每个页面到达时,您都会更新进度条。如果页面请求失败,只需重试该请求并继续处理。与尝试在一次大规模请求中获取所有 10 万个联系人相比,这应该是一种更加可靠和高效的方法。

You can first ask the web service for the total number of contacts it has (say 100,000), and then ask it for individual "pages" of contacts (say 100 contacts/page). As each page arrives, you update the progress bar. If a page request fails just retry that request and continue processing. This should be a much more reliable and efficient approach than trying to get all 100k contacts in one massive request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文