简体   繁体   English

为什么在使用InputStream Read后,我的Sax解析器没有任何结果?

[英]Why does my Sax Parser produce no results after using InputStream Read?

I have this piece of code which I'm hoping will be able to tell me how much data I have downloaded (and soon put it in a progress bar), and then parse the results through my Sax Parser. 我有这段代码,希望能够告诉我已下载了多少数据(并很快将其放在进度栏中),然后通过我的Sax Parser解析结果。 If I comment out basically everything above the //xr.parse(new InputSource(request.getInputStream())); 如果我基本上注释掉//xr.parse(new InputSource(request.getInputStream()))以上的所有内容 line and swap the xr.parse's over, it works fine. 行并交换xr.parse的结束,它工作正常。 But at the moment, my Sax parser tells me I have nothing. 但是此刻,我的Sax解析器告诉我我什么都没有。 Is it something to do with is. 与它有关。 read (buffer) section? (缓冲区)部分?

Also, just as a note, request is a HttpURLConnection with various signatures. 另外,请注意,请求是带有各种签名的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. */;

Can anyone help me at all?? 谁能帮我吗?

Kind regards, 亲切的问候,

Andy 安迪

'I could only find a way to do that with bytes, unless you know another method?'. “除非您知道另一种方法,否则我只能找到一种使用字节的方法?”。

But you haven't found a method. 但是您还没有找到一种方法。 You've just written code that doesn't work. 您刚刚编写了无效的代码。 And you don't want to save the input to a String either. 而且您也不想将输入保存到字符串。 You want to count the bytes while you're parsing them. 您想在解析字节计算字节数 Otherwise you're just adding latency, ie wasting time and slowing everything down. 否则,您只是在增加延迟,即浪费时间并放慢一切。 For an example of how to do it right, see javax.swing.ProgressMonitorInputStream. 有关如何正确执行此操作的示例,请参见javax.swing.ProgressMonitorInputStream。 You don't have to use that but you certainly do have to use a FilterInputStream of some sort, probaby one you write yourself, that is wrapped around the request input stream and passed to the parser. 您不必使用它,但是您确实必须使用某种FilterInputStream,可能是您自己编写的,它包装在请求输入流中并传递给解析器。

You can save your data in a file, and then read them out. 您可以将数据保存在文件中,然后将其读出。

    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));
}

Your while loop is consuming the input stream and leaving nothing for the parser to read. while循环正在消耗输入流,而使解析器无法读取任何内容。

For what you're trying to do, you might want to look into implementing a FilterInputStream subclass wrapping the input stream. 对于您要尝试执行的操作,您可能需要研究实现包装输入流的FilterInputStream子类。

You are building an InputStream over another InputStream that consumes its data before. 您正在一个之前使用其数据的另一个InputStream上构建一个InputStream

If you want to avoid reading just single bytes you could use a BufferedInputStream or different things like a BufferedReader . 如果要避免只读取单个字节,则可以使用BufferedInputStream或其他类似BufferedReader东西。

In any case it's better to obtain the whole content before parsing it! 无论如何,最好在解析之前获取全部内容! Unless you need to dynamically parse it. 除非您需要动态解析它。

If you really want to keep it on like you are doing you should create two piped streams: 如果您真的想像做的那样继续使用它,则应创建两个管道流:

PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream();

pipeIn.connect(pipeOut);

pipeOut.write(yourBytes);

xr.parse(pipeIn);

Streams in Java, like their name suggest you, doesn't have a precise dimension neither you know when they'll finish so whenever you create an InputStream , if you read from them you cannot then pass the same InputStream to another object because data is already being consumed from the former one. Java流就像它们的名字一样暗示着您,它也不知道精确的尺寸,因此也不知道它们何时会完成,因此,每当创建InputStream ,如果您从它们中读取,就无法将同一InputStream传递给另一个对象,因为数据是已经被前者消耗掉了。

If you want to do both things (downloading and parsing) together you have to hook between the data received from the HTTPUrlConncection you should: 如果要同时进行这两种操作(下载和解析),则必须在从HTTPUrlConncection接收到的数据之间进行挂钩,您应该:

  • first know the length of the data being downloaded, this can be obtained from HttpUrlConnection header 首先知道要下载的数据的长度,这可以从HttpUrlConnection标头获得
  • using a custom InputStream that decorates (this is how streams work in Java, see here ) updading the progressbar.. 使用自定义InputStream来装饰进度条(这是Java中流的工作方式,请参见此处 )。

Something like: 就像是:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM