1

再利用に関する投稿が多数あることがわかりますInputStreamInputStreamこれは 1 回限りのものであり、再利用できないことを理解しています。

ただし、次のようなユースケースがあります。

を使用してDropBoxを取得して、からファイルをダウンロードしました。次に、 を渡して、ファイルを別のシステムにアップロードする必要があります。ただし、ダウンロードの一部として、ファイルの を提供する必要があります。そのため、ファイルをアップロードする前に、ストリームからファイルを読み取る必要があります。受け取った は 1 回しか使用できないため、を計算してからファイルをアップロードする前に、別のファイルを取得する必要があります。手順は次のようになります。DropBoxInputStreamDropBox's Java SDKInputStreamMD5DropBoxInputStreamDropBoxInputStreamMD5

  1. 最初の DropBoxInputStream を取得する
  2. DropBoxInputStream から読み取り、MD5 を計算します
  3. 2 番目の DropBoxInputStream を取得する
  4. MD5 と 2 番目の DropBoxInputStream を使用してファイルをアップロードします。

InputStream計算する前に「キャッシュ」または「バックアップ」する方法がたくさんある場合、同じものを再度MD5取得するステップ3を節約できると思いますか?DropBoxInputStream

どうもありがとう

編集:

申し訳ありませんが、いくつかの情報を見逃していました。

私が現在行っていることは、 a を使用してMD5DigestOutputStreamを計算することMD5です。でデータをストリーミング MD5DigestOutputStreamし、一時ファイルとしてローカルに保存します。データが を通過するMD5DigestOutputStreamと、 が計算されMD5ます。

次に、サードパーティのライブラリを呼び出して、計算された md5 とFileInputStream一時ファイルから読み取る a を使用してファイルをアップロードします。

ただし、これには巨大なディスク容量が必要になる場合があり、一時ファイルを使用する必要をなくしたいと考えています。MD5私が使用するライブラリは aとのみを受け入れますInputStream。これはMD5、自分の側で を計算する必要があることを意味します。私の計画は、 my を使用して (ファイルを保持せずに)MD5DigestOutputStreamデータを書き込ん/dev/nullで、 を計算しMD5、DropBox から を再度取得して、InputStream使用するライブラリに渡すことです。ライブラリはDropBox、ディスクのメモリまたはメモリにファイルをキャッシュする必要なく、ファイルを直接取得できると思います。それはうまくいきますか?

4

2 に答える 2

3

入力ストリームは、実際にはコピーの作成や再利用のために設計されたものではありません。特に、バイト配列に読み取って配列操作を使用したくない場合に使用します (これは、配列全体がソケット通信などでは使用できません)。これは、十分な情報が得られるまで、ストリームからバイト配列バッファーにセクションを読み取るプロセスです。

しかし、それは md5 の計算には不要です。InputStreamは抽象的であるため、拡張クラスで実装する必要があることに注意してください。、fileinputstream などの多くの実装がありますGZIPInputStream。これらは、設計パターンで言えば、IO ストリームのデコレーターです。これらは、抽象基本 IO クラスに追加機能を追加します。たとえばGZIPInputStream、ストリームを gzip します。

したがって、必要なのは、md5 でこれを行うためのストリームです。嬉しいことに、よく文書化された同様のことがあり、この回答を参照してください。したがって、ドロップボックス入力ストリームを渡して(それ自体が入力ストリームになるため)新しい を作成するDigestInputStreamだけで、 md5 を取得して以前と同じように読み続けることができます。

型キャストが心配ですか? Java のデコレーターの考え方は、InputStream 基本クラスがすべてのメソッドと IO を実行するために必要な「ビーフ」のインターフェイスであるInputStreamため、各ストリーム実装のコンストラクターで継承するオブジェクトのインスタンスを渡すことに害はなく、それでもできるということです。同じコア IO を実行します。

最後に、おそらくあなたの実際の質問に答える必要があります-とにかくストリームを「キャッシュ」または「バックアップ」したいと言いますか? まあ、それをバイト配列に書き込むことができます。これは十分に文書化されていますが、ストリームがより複雑になると、おかしくなる可能性があります。または、 を見てみてくださいPushbackInputStream。ここでは、n バイトを読み取り、実行して操作し、ストリームに復元する関数を簡単に作成できます。Java でのストリームのこれらの実装はメモリの使用に悪いため、一般的には避けるのが良いですが、そうでなければしなければならないすべてをバッファリングするよりも悪くありません。

または、もちろん、私はDigestInputStream.

お役に立てれば、

一番。

于 2013-05-23T09:14:45.160 に答える
1

You don't need to open a new InputStream from DropBox.

ファイルを DropBox から読み取ったら、ローカルに保存します。つまり、メモリ内 (バイト配列内) にあるか、ローカル ファイルに格納されています。これで、ファイルをアップロードするためにメモリ (ByteArrayInputStream) またはディスク (FileInputStream) からデータを読み取る InputStream を作成できます。

そのため、InputStream をキャッシュする (できない) 代わりに、コンテンツをキャッシュします (できる)。

于 2013-05-23T08:39:56.713 に答える