Java 为什么我的Sax解析器在使用InputStream读取后不产生任何结果?
我有一段代码,我希望它能够告诉我下载了多少数据(并很快将其放入进度条),然后通过我的Sax解析器解析结果。如果我注释掉//xr.parse(newInputSource(request.getInputStream())上面的所有内容;行并交换xr.parse。解析完成后,工作正常。但是现在,我的Sax解析器告诉我我什么都没有。这与Is.读取(缓冲区)部分有关吗 另外,请注意,请求是一个带有各种签名的HttpURLConnectionJava 为什么我的Sax解析器在使用InputStream读取后不产生任何结果?,java,android,sax,httpurlconnection,Java,Android,Sax,Httpurlconnection,我有一段代码,我希望它能够告诉我下载了多少数据(并很快将其放入进度条),然后通过我的Sax解析器解析结果。如果我注释掉//xr.parse(newInputSource(request.getInputStream())上面的所有内容;行并交换xr.parse。解析完成后,工作正常。但是现在,我的Sax解析器告诉我我什么都没有。这与Is.读取(缓冲区)部分有关吗 另外,请注意,请求是一个带有各种签名的HttpURLConnection /*Input strea
/*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. */;
/*要从我们的连接读取的输入流*/
InputStream=request.getInputStream();
/*我们使用2 Kb的缓冲区来加速下载,而不是一次读取一个字节的文件*/
字节[]缓冲区=新字节[2048];
/*我们已经下载了多少字节*/
int totBytes,bytes,sumBytes=0;
totBytes=request.getContentLength();
虽然(正确){
/*我们得到了多少字节*/
字节=is.read(缓冲区);
/*如果没有更多字节,我们就完成下载*/
如果(byteswhile循环正在消耗输入流,并且没有留下任何内容供解析器读取
对于您正在尝试做的事情,您可能需要考虑实现一个包装输入流的FilterInputStream子类。您正在构建一个InputStream
而另一个InputStream
之前会消耗其数据
如果要避免只读取单个字节,可以使用BufferedInputStream
或其他类似BufferedReader
的东西
在任何情况下,最好在解析之前获取整个内容!除非您需要动态解析它
如果您真的想像现在这样继续运行,您应该创建两个管道流:
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream();
pipeIn.connect(pipeOut);
pipeOut.write(yourBytes);
xr.parse(pipeIn);
Java中的流,正如它们的名字所暗示的那样,没有精确的维度,也不知道它们什么时候会结束。因此,无论何时创建InputStream
,如果从它们读取数据,就不能将相同的InputStream
传递给另一个对象,因为数据已经从前一个对象中消耗
如果您想同时完成这两项工作(下载和解析),则必须在从httpurlconcection
接收的数据之间挂接,您应该:
- 首先要知道下载数据的长度,这可以从
HttpUrlConnection
头中获得
- 使用定制的InputStream来装饰(这是Java中流的工作方式,请参阅)升级progressbar
比如:
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);
“我只能找到一个办法
用字节,除非你知道另一个
方法
但是您还没有找到一个方法。您只是编写了不起作用的代码。而且您也不想将输入保存到字符串中。您想在解析字节时计算字节数。否则,您只会增加延迟,即浪费时间并降低速度。有关如何正确操作的示例,请参阅javax.swing.ProgressMonitorInputtStream。您不必使用它,但您肯定必须使用某种类型的FilterInputStream,可能是您自己编写的,它被包装在请求输入流周围并传递给解析器。您可以将数据保存在文件中,然后读取它们
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));
}
这听起来很复杂!我可以在任何地方找到示例吗?事实上,它并没有那么复杂。关于示例,有一个stackoverflow问题-请参阅如何找到示例的简短答案,即在Java SDK安装中找到src.jar。正如另一个答案中所述,javax.swing.ProgressMonitorInputStream是一个很好的示例在,做你想做的事情,但是在Swing环境中。我知道所有返回的数据都将是XML,如果这有什么帮助的话。如果能够看到下载的进度,那就太好了,我只能找到一种用字节来完成的方法,除非你知道另一种方法。我如何保存第一次运行,在它得到多少读取量的地方,将其保存为字符串…因为我确信InputSource接受字符串!+1,用于指向实际执行进度监控的源,尽管他需要编写一个非swing版本。