java - 为什么当我使用 BufferedReader 时,InputStream 会关闭?

标签 java android inputstream bufferedreader

当我读取 InputStream 并尝试再次使用它时,出现此错误。

07-20 17:36:24.762  11253-11277/? W/System.err﹕ java.io.IOException
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at java.io.InputStream.reset(InputStream.java:208)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at demo31.com.maps.GMapDirections$DownloadDocumentTask.doInBackground(GMapDirections.java:134)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at demo31.com.maps.GMapDirections$DownloadDocumentTask.doInBackground(GMapDirections.java:86)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at javautil.concurrent.FutureTask.run(FutureTask.java:237)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-20 17:36:24.762  11253-11277/? W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
07-20 17:36:24.762  11253-11277/? D/GMapDirections﹕ Exception while downloading data: java.io.IOException

我正在使用的代码是...

@Override
protected Document doInBackground(ArrayList... latLngs) {
  Log.d(TAG, "DownloadDocumentTask(doInBackground): Estoy dentro del background!!!");
  try {
    HttpsURLConnection urlConnection;
    FileService file = new FileService();
    InputStream iStream;
    Document result;

    file.writeLog(TAG, GMapDirections.class.getName(), getUrlConnection());

    URL url = new URL(getUrlConnection());

    // Creating an http connection to communicate with url
    urlConnection = (HttpsURLConnection) url.openConnection();

    // Connecting to url
    urlConnection.setRequestMethod("POST");
    urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    urlConnection.setRequestProperty("charset", "utf-8");
    urlConnection.setRequestProperty("Accept", "application/xml");
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.setUseCaches(false);
    urlConnection.connect();

    //Return data
    iStream = urlConnection.getInputStream();

    //Display what returns POST request
    BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
    StringBuilder sb = new StringBuilder();

    String line;
    while ((line = br.readLine()) != null) {
      sb.append(line + "\n");
    }
    br.close();
    file.writeLog(GMapDirections.TAG, "doInBackground", sb.toString());

    // Parse the data to a Document Object
    DocumentBuilder builder =  DocumentBuilderFactory.newInstance().newDocumentBuilder();
    result = builder.parse(iStream);
    urlConnection.disconnect();

    return result;
  } catch (Exception e) {
     e.printStackTrace();
     Log.d(TAG, "Exception while downloading data: " + e.toString());
  }
  return null;
}

当我尝试解析 iStream 的内容时,会引发异常,因为之前我已经使用 BufferedReader 读取了它。

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
result = builder.parse(iStream);

那么,我如何使用 BufferedReader 读取 iStream,然后用它来解析内容而不出现错误?

最佳答案

您的堆栈跟踪和代码似乎不匹配。从堆栈跟踪来看,doInBackground 正在递归调用自身,然后调用 InputStream.reset()。但我在你的代码中看不到这两个调用。

关于重新读取流的实际问题: 由于您显然已经尝试过(但失败了)InputStream.reset(),因此该流中的数据量可能太大(或者您忘记调用InputStream.mark())。最简单的方法是创建另一个连接+流并读取它。这确实意味着您实际上会低效地从 URL 传输该数据两次。

更有效的方法来做到这一点:

  1. 将流的全部内容读入内存/或临时文件(取决于大小),然后将其用作数据源。

  2. 使用 TeeInputStream ( https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/TeeInputStream.html ) 随时复制流数据。

关于java - 为什么当我使用 BufferedReader 时,InputStream 会关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31520866/

相关文章:

java - 越界异常(字符串)

Java OO 设计 : a Person can be either Singer, 钢琴家或两者

java - 'this'关键字在另一个类文件中的使用

node.js - 使用express的nodejs输入流

java.io.FileNotFoundException 访问被拒绝

Java:InputStreamReader字符编码需要运行两次

java - 在 Apache Ant 中使用 <java> 标签,我可以同时运行 Server 和 Proxy Server 类吗

java - 工厂模式和策略模式有什么区别?

android - 我怎样才能打开安卓摄像机的高清模式?

android - IBM Worklight Android 4.4 问题,JSON Store 停止工作