【问题标题】:Why does my Sax Parser produce no results after using InputStream Read?为什么我的 Sax Parser 在使用 InputStream Read 后没有产生任何结果?
【发布时间】:2010-03-26 01:09:01
【问题描述】:

我有这段代码,我希望它能够告诉我下载了多少数据(并很快将其放入进度条中),然后通过我的 Sax Parser 解析结果。如果我基本上注释掉 //xr.parse(new InputSource(request.getInputStream())); 行上方的所有内容并交换 xr.parse 的结束,它工作正常。但此刻,我的 Sax 解析器告诉我我什么都没有。它与 is.read(缓冲区)部分有关吗?

另外,请注意,request 是一个带有各种签名的 HttpURLConnection。

                 /*Input stream to read from our connection*/ 
                 InputStream is = request.getInputStream();
                 /*we make a 2 Kb buffer to accelerate the download, instead of reading the file a byte at once*/ 
                 byte [  ]  buffer = new byte [ 2048 ] ;

                 /*How many bytes do we have already downloaded*/ 
                 int totBytes,bytes,sumBytes = 0; 
                 totBytes = request.getContentLength () ; 

                 while  ( true )  {  

                     /*How many bytes we got*/ 
                         bytes = is.read (buffer);

                         /*If no more byte, we're done with the download*/ 
                         if  ( bytes  <= 0 )  break;       

                         sumBytes+= bytes;

                         Log.v("XML", sumBytes + " of " + totBytes + " " + (  ( float ) sumBytes/ ( float ) totBytes ) *100 + "% done" ); 


                 }
                 /* Parse the xml-data from our URL. */
                 // OLD, and works if comment all the above 
                 //xr.parse(new InputSource(request.getInputStream()));
                 xr.parse(new InputSource(is))
                 /* Parsing has finished. */;

任何人都可以帮助我吗??

亲切的问候,

安迪

【问题讨论】:

    标签: java android sax httpurlconnection


    【解决方案1】:

    '我只能找到一种方法来做到这一点 用字节,除非你知道另一个 方法?'。

    但是您还没有找到方法。您刚刚编写了不起作用的代码。而且您也不想将输入保存到字符串。您想在解析字节时计算字节数。 否则,您只是在增加延迟,即浪费时间并减慢一切速度。有关如何正确执行此操作的示例,请参阅 javax.swing.ProgressMonitorInputStream。您不必使用它,但您当然必须使用某种 FilterInputStream,可能是您自己编写的,它包裹在请求输入流周围并传递给解析器。

    【讨论】:

    • +1 用于指向实际进行进度监控的源,尽管他需要编写一个非 swing 版本。
    【解决方案2】:

    您的 while 循环正在消耗输入流,并且没有任何内容可供解析器读取。

    对于您正在尝试做的事情,您可能希望研究实现一个包装输入流的 FilterInputStream 子类。

    【讨论】:

    • 听起来很复杂!我可以在哪里找到示例?
    • 其实并没有那么复杂。有一个关于示例的 stackoverflow 问题 - 请参阅 stackoverflow.com/questions/765473/…
    • 关于如何查找示例的简短答案是在您的 Java SDK 安装中找到 src.jar。正如另一个答案中所指出的,javax.swing.ProgressMonitorInputStream 是一个很好的例子,它完全按照您的意愿去做,但是在 Swing 上下文中。
    【解决方案3】:

    您正在构建一个InputStream,而不是另一个之前使用其数据的InputStream

    如果您想避免只读取单个字节,您可以使用BufferedInputStreamBufferedReader 等不同的东西。

    无论如何,最好在解析之前获取全部内容!除非你需要动态解析它。

    如果您真的想像现在一样继续使用它,您应该创建两个管道流:

    PipedOutputStream pipeOut = new PipedOutputStream();
    PipedInputStream pipeIn = new PipedInputStream();
    
    pipeIn.connect(pipeOut);
    
    pipeOut.write(yourBytes);
    
    xr.parse(pipeIn);
    

    Java 中的流,就像它们的名字所暗示的那样,没有精确的维度,你也不知道它们何时会完成,所以每当你创建一个 InputStream 时,如果你从它们那里读取,你就不能传递相同的 @987654328 @ 到另一个对象,因为数据已经被前一个对象消耗了。

    如果你想同时做这两件事(下载和解析),你必须在从HTTPUrlConncection接收的数据之间挂钩,你应该:

    • 先知道正在下载的数据的长度,这个可以从HttpUrlConnectionheader中得到
    • 使用自定义 InputStream 进行装饰(这就是流在 Java 中的工作方式,请参阅 here)更新进度条..

    类似:

    class MyInputStream extends InputStream
    {
      MyInputStream(InputStream is, int total)
      {
        this.total = total;
      }
    
      public int read()
      {
        stepProgress(1);
        return super.read();
      }
    
      public int read(byte[] b)
      {
        int l = super.read(b);
        stepProgress(l);
        return l;
      }
    
      public int read(byte[] b, int off, int len)
      {
        int l = super.read(b, off, len);
        stepProgress(l);
        return l
      }
    }
    
    
    
    InputStream mis= new MyInputStream(request.getInputStream(), length);
    ..
    xr.parse(mis);
    

    【讨论】:

    • 好吧,我知道如果有任何帮助,所有返回的数据都将是 XML。很高兴能够看到它的下载进度,我只能找到一种使用字节的方法,除非你知道另一种方法?
    • 我怎样才能保存第一次运行它得到多少读取,将它保存到一个字符串......因为我确定 InputSource 接受字符串!
    【解决方案4】:

    您可以将数据保存在文件中,然后将其读出。

        InputStream is = request.getInputStream();
    if(is!=null){
    File file = new File(path, "someFile.txt");
    FileOutputStream os = new FileOutputStream(file);
    buffer = new byte[2048];
    bufferLength = 0;
        while ((bufferLength = is.read(buffer)) > 0) 
        os.write(buffer, 0, bufferLength);
    
    os.flush();
    os.close();
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    factory.setNamespaceAware(true);
    XmlPullParser xpp = factory.newPullParser();
    FileInputStream fis = new FileInputStream(file);
    xpp.setInput(new InputStreamReader(fis));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 2020-09-23
      • 2019-02-03
      相关资源
      最近更新 更多