InputStream Read を使用した後、Sax パーサーが結果を生成しないのはなぜですか?
-
22-09-2019 - |
質問
私がダウンロードしたデータの量を教えて (すぐにプログレスバーに表示して)、その結果を Sax パーサーで解析できることを期待しているこのコードがあります。基本的に上記のすべてをコメントアウトすると、 //xr.parse(new InputSource(request.getInputStream())); 行を変更して xr.parse を交換すると、正常に動作します。しかし現時点では、Sax パーサーは私に何も持っていないと言います。何か関係があるのでしょうか。読む (バッファ)セクション?
また、注意事項として、リクエストはさまざまな署名付きの 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. */;
誰か私を手伝ってくれませんか??
敬具、
アンディ
解決
'私はそれを行うための方法を見つけることができます バイトで、あなたは別のを知っていない限り、 方法?」ます。
しかし、の持っていないの方法を発見しました。あなただけでは動作しないコードを書いています。そして、あなたはどちらかの文字列の入力を保存しません。あなたは、あなたがそれらを解析している間、<全角>バイトをカウントしたい。のそれ以外の場合は、あなただけの、つまり無駄時間を、待ち時間を追加し、すべてのダウンを遅くしています。右のそれを行う方法の例については、javax.swing.ProgressMonitorInputStreamのを参照してください。あなたはしかし、あなたは確かにある種のFilterInputStream、要求の入力ストリームに巻き付けとパーサーに渡され、自分で書くprobabyのいずれかを使用する必要がないことを使用する必要はありません。
他のヒント
あなたのwhileループは、入力ストリームを消費し、読むためにパーサのために何も残されていません。
あなたが何をしようとしてためには、入力ストリームFilterInputStreamサブクラスラッピングを実装するに見たいと思うかもしれません。
あなたは、 InputStream
別の InputStream
以前にデータを消費します。
単一バイトのみの読み取りを避けたい場合は、 BufferedInputStream
または、 BufferedReader
.
いずれの場合も、解析する前にコンテンツ全体を取得することをお勧めします。動的に解析する必要がある場合を除きます。
本当にこのままにしておきたい場合は、2 つのパイプされたストリームを作成する必要があります。
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream();
pipeIn.connect(pipeOut);
pipeOut.write(yourBytes);
xr.parse(pipeIn);
Java のストリームには、その名前が示すように、正確なディメンションがなく、いつ終了するかわからないため、ストリームを作成するたびに InputStream
, 、それらから読み取る場合、同じものを渡すことはできません InputStream
データはすでに前のオブジェクトから消費されているため、別のオブジェクトに移動します。
両方のこと (ダウンロードと解析) を一緒に実行したい場合は、 HTTPUrlConncection
あなたがすべき:
- まず、ダウンロードされるデータの長さを知ります。これは次から取得できます。
HttpUrlConnection
ヘッダ - 装飾するカスタム 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);
あなたは、ファイルにデータを保存し、それらを読むことができます。
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));
}