bytearrayoutputStreamのパブリックインターフェイスの設計の正当化?

StackOverflow https://stackoverflow.com/questions/6325596

  •  27-10-2019
  •  | 
  •  

質問

多くのJava標準およびサードパーティの図書館があり、公開APIには、書くか読む方法があります。 Stream。一例は次のとおりです javax.imageio.ImageIO.write() それには必要です OutputStream 処理された画像のコンテンツを書くには。別の例は次のとおりです itext PDF処理ライブラリ OutputStream 結果のPDFを記述します。 3番目の例は、Amazons3 Java APIです InputStream それはそれを読み、3でファイルを作成します S3ストレージ.

問題は、これらの2つを組み合わせたい場合に動揺します。たとえば、画像があります BufferedImage 私はそれを使わなければなりません ImageIO.write 結果をプッシュします OutputStream. 。しかし、ノーはありません 直接 S3が必要とするように、それをAmazonS3にプッシュする方法 InputStream.
これを解決する方法はほとんどありませんが、この質問の主題はの使用です ByteArrayOutputStream.

背後にあるアイデア ByteArrayOutputStream 包まれた間層BYTEアレイを使用することです Input/Output Stream 出力ストリームに書き込みたい人が配列に書き込み、読みたい人が配列を読むようにします。

私の不思議はなぜです ByteArrayOutputStream たとえば、コピーすることなくバイト配列へのアクセスを許可しないでください。 InputStream それはそれに直接アクセスできます。それにアクセスする唯一の方法は、呼び出すことです toByteArray(), 、それは内部配列(標準の配列)のコピーを作成します。つまり、私の画像の例では、 メモリ内の画像のコピー:

  • 初め 実際です BufferedImage,
  • 2番目 内部です arrayOutputStream
  • 三番 によって作成されたコピーです toByteArray() だから私は作成することができますInputStream.

このデザインはどのように正当化されますか?

  • 実装を隠す?提供するだけです getInputStream(), 、および実装は隠されたままです。
  • マルチスレッド? ByteArrayOutputStream とにかく複数のスレッドによるアクセスに適していないため、これはできません。

さらに、2番目の風味があります ByteArrayOutputStream, 、Apache'sによって提供されます Commons-Io ライブラリ(異なる内部実装があります)。しかし、どちらもまったく同じです 公衆 バイト配列をコピーせずにアクセスする方法を提供しないインターフェイス。

役に立ちましたか?

解決

幸いなことに、内部配列はです protected, 、したがって、あなたはそれをサブクラス化し、ラップすることができます ByteArrayInputStream コピーなしで、その周り。

他のヒント

私の不思議は、たとえば、それに直接アクセスできる入力ストリームを提供するために、それを対処せずにバイト配列にアクセスできない理由です。

私は4つの理由を考えることができます:

  • 現在の実装では、単一のバイト配列を使用しますが、バイト配列のリンクリストとして実装することもでき、アプリケーションが要求されるまで最終配列の作成を延期することもできます。アプリケーションが実際のバイトバッファーを確認できれば、 持ってる 単一の配列になること。

  • あなたの理解に反して ByteArrayOutputStream 安全にスレッド、そして マルチスレッドアプリケーションでの使用に適しています。しかし、バイト配列に直接アクセスが提供された場合、他の問題を作成せずにどのように同期することができるかを確認することは困難です。

  • アプリケーションは、現在のバッファーハイウォーターマークがどこにあるか、およびバイト配列が(まだ)ライブバイトアレイであるかどうかを知る必要があるため、APIはより複雑にする必要があります。 ( ByteArrayOutputStream 実装は、バイト配列を再配置する必要がある場合があります...そして、それはもはやないアレイへの参照を保持するアプリケーションを残します 配列。)

  • バイト配列を公開すると、アプリケーションが配列の内容を変更できるようにします。 になり得る 問題があります。


このデザインはどのように正当化されますか?

デザインは、あなたのものよりも単純なユースケースに合わせて調整されています。 Java SEクラスライブラリは、可能なすべてのユースケースをサポートすることを目指していません。しかし、彼らはあなた(またはサードパーティライブラリ)が他のユースケースに他のストリームクラスを提供することを妨げません。


一番下の行は、サンデザイナーがバイト配列を公開しないことを決めたということです ByteArrayOutputStream, 、そして(IMO)あなたは彼らの心を変えることはほとんどありません。

(そして、もしあなたが試してみたいなら、これはそれをするのに適した場所ではありません。

  • バグデータベースを介してRFEを送信してみてください。
  • または、機能を追加するパッチを開発し、関連するチャネルを介してOpenJDKチームに送信します。包括的なユニットテストとドキュメントを含めた場合、チャンスを増やします。)

Apache Commons Io開発者に、あまり危険ではないAPIデザインを思い付くことができる限り、より多くの成功を収めることができます。

または、内部データ構造を公開する独自の特別な目的バージョンを実装することを妨げるものはありません。コードはgpl'edであるため、コピーすることができます...コード配布に関する通常のGPLルールの対象となります。

私はあなたが探している行動は パイプ. 。 bytearrayoutputStreamは、出力ストリームであり、入力/出力ストリームではありません。それはあなたが念頭に置いているもののために設計されていませんでした。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top