Почему мой Sax Parser не дает результатов после использования InputStream Read? - PullRequest
0 голосов
/ 26 марта 2010

У меня есть этот фрагмент кода, который, я надеюсь, сможет сказать мне, сколько данных я скачал (и скоро поместит его в индикатор выполнения), а затем проанализировать результаты через мой Sax Parser. Если я закомментирую в основном все, что выше строки // xr.parse (new InputSource (request.getInputStream ())); , и поменяю местами xr.parse, то все будет нормально. Но в данный момент мой синтаксический анализатор Sax говорит мне, что у меня ничего нет. Это как-то связано с разделом *. 1003 * read (буфер)?

Также, как примечание, запрос представляет собой соединение HttpURLC с различными сигнатурами.

                 /*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. */;

Может ли кто-нибудь помочь мне вообще ??

С уважением,

Andy

Ответы [ 4 ]

1 голос
/ 26 марта 2010

«Я мог только найти способ сделать это с байтами, если вы не знаете другого метод?».

Но вы не не нашли метод. Вы только что написали код, который не работает. И вы также не хотите сохранять входные данные в строку. Вы хотите посчитать байты во время их анализа. В противном случае вы просто добавляете задержку, т. Е. Тратите время и все замедляете. Для примера того, как сделать это правильно, см. Javax.swing.ProgressMonitorInputStream. Вам не нужно это использовать, но вам обязательно нужно использовать какой-то FilterInputStream, вероятно, тот, который вы пишете самостоятельно, который оборачивается вокруг потока ввода запроса и передается в анализатор.

0 голосов
/ 24 сентября 2012

Вы можете сохранить свои данные в файл, а затем прочитать их.

    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));
}
0 голосов
/ 26 марта 2010

Вы строите InputStream над другим InputStream, который потребляет свои данные раньше.

Если вы хотите избежать чтения только одного байта, вы можете использовать BufferedInputStream или другие вещи, такие как BufferedReader.

В любом случае лучше получить весь контент перед его разбором! Если вам не нужно динамически разобрать его.

Если вы действительно хотите оставить его включенным, вам нужно создать два потоковых канала:

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

pipeIn.connect(pipeOut);

pipeOut.write(yourBytes);

xr.parse(pipeIn);

Потоки в Java, как следует из их названия, не имеют точного измерения, и вы не знаете, когда они закончат, поэтому всякий раз, когда вы создаете InputStream, если вы читаете из них, вы не можете передать тот же InputStream к другому объекту, потому что данные уже используются из предыдущего.

Если вы хотите сделать обе вещи (загрузку и синтаксический анализ) вместе, вы должны подключиться к данным, полученным от HTTPUrlConncection, вам следует:

  • сначала узнайте длину загружаемых данных, это можно получить из HttpUrlConnection header
  • с использованием пользовательского InputStream, который декорирует (так работают потоки в Java, см. здесь ), обновляя индикатор выполнения ..

Что-то вроде:

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);
0 голосов
/ 26 марта 2010

Ваш цикл while потребляет входной поток и не оставляет ничего для чтения анализатором.

Для того, что вы пытаетесь сделать, вам может понадобиться реализация подкласса FilterInputStream, обертывающего входной поток.

...