1

質問は一般的なものかもしれませんが、ここでの主な意味を理解しようとしています。ByteArrayInputStreamを使用して「正しい」マーク/リセット動作を行う危険性/保証

BCELライブラリを使用してバイトコードエンジニアリングを実行しようとしており、ワークフローの一部では、同じバイトコードファイルを複数回(最初から)読み込む必要があります。流れは次の通りです

// 1. Get Input Stream 

// 2. Do some work 

// 3. Finish 

// 4. Do some other work. 

手順4では、マークをリセットするか、ストリームを最初から取得する必要があります。私は以下の選択肢を知っています。

1)BufferedInputStreamを使用してストリームをラップ - 「マークを無効なリセット」取得のチャンスにIOException

2)するByteArrayInputStreamを使用して、それをラップ - それは常にいくつかのオンライン調査は、それが誤っだことを示唆しているにもかかわらず動作しますか?

3)ストリームからもう一度読む必要がある場合は、getInputStream()に電話するだけです。

私はどちらのオプションが良いのか理解しようとしています。最後のmarkが呼び出された場所がないので、BufferedInputStreamを使用したくないので、より高いマーク位置にresetを呼び出すとIOExceptionが発生します。 ByteArrayInputStreamを使用する方が好きですが、それは最低限のコード変更が必要ですが、誰かがオプション#2かオプション#3のどちらが良いかどうかを提案できますか?

JDKのByteArrayInputStreamBufferedInputStreamでは、mark()とreset()の実装が異なることがわかりました。

よろしく

+0

ですから、基本的に '.class'ファイルになる' File'を読んでいますか?一度それを読んで、それをバイト配列に格納するのはなぜですか? – Eugene

+0

@Eugeneはい私はすでにそれをやっています - それはうまくいきますが、私は信者または "専門家の意見"であり、私が考慮しなかった可能性のあるキャッチがあることを期待しています。あなたは何かを知っていますか? – ha9u63ar

+0

入力ストリーム全体を読みたくない場合は、markとresetを使用することが重要です。または次に何をするかを知るために次の数バイトを読みたいと思っています。それ以外の場合は配列に読み込むのが最も簡単です(と私にとってはっきりしています) – Eugene

答えて

3

mark/resetの問題は、事前にこれらの呼び出しの間で読まれているデータの最大量を知るために、あなたはまた、コードは、あなたが意志に委任しているかどうかを知っている必要がありますしているということだけではありませんその機能を内部的に使用して、マークを廃止します。 mark/resetを使用しているコードでは、発信者の前のマークを覚えて復元することは不可能です。

合計ファイルサイズを最大でreadlimitと指定することで最大の問題を解決することは可能ですが、使用しないことを明示的に文書化していない任意のライブラリ関数にInputStreamを渡すときには、内部ではmark/reset機能です。

また、readlimitのファイルサイズの合計がreadlimitになると、同じサイズのバッファを維持するため、ファイル全体を保持する配列をラップするよりも効率的ではありません。


最高の解決策は、クラスファイル全体を一度アレイに読み込み、アレイを直接使用することです。 (ASMのClassReaderは、例えば、InputStreamの代わりにバイト配列を使用することをサポートしています)。あなたがそれを主張ライブラリ関数にInputStreamを供給する必要がある場合

、BCELのように、その後、必要なときにByteArrayInputStreamにバイト配列をラップしますが、は、クラスを再解析し、あなたが持っている新しいByteArrayInputStreamたびに作成ファイル。新しいByteArrayInputStreamを構築するのは、古い入力ストリームの状態には依存しないため、軽量ラッパーで信頼性が高いため、何もコストがかかりません。同時に複数のByteArrayInputStreamインスタンスで同じ配列を読み取ることもできます。

getInputStream()をもう一度呼び出すと、コンテンツ全体のバッファリングがオプションではない非常に大きなファイルに対処する必要がある場合は、オプションになりますが、これはクラスファイルには当てはまりません。

+0

私は実際にファイルの内容(バイト[])を 'ByteArrayInputStream'にラップし、それを渡します - APIの最小変更 - これは私のために働く。あなた自身と@Eugeneの両方のように見えますが、これはあなたのコメントにあります。今私はこれに満足しています。 – ha9u63ar

関連する問題