2016-09-20 3 views
0

私はPDF文書を生成し、それをOutputStreamに書き込むライブラリを持っています。 OutputStreamはPDFライブラリに渡されます。結果データをList<Byte[]>List<byte[]>に保存する必要があり、各エントリの長さは255バイトに固定されています。私のバイトチャンクのリストを直接出力するOutputStream

ここで最も簡単な解決策は、ByteArrayOutputStreamを使用して、結果のバイト配列をバイト配列リストに書き込む(そして逆アセンブルする)ことです。

しかし、私はより少ないメモリを必要とするより効率的なソリューションが必要です。出力ストリームでバイト配列リストを直接生成したい。

私の解決策は、OutputStreamを上書きし、write()を上書きして、List<byte[]>に直接書き込んでください。

これは、すでに受け入れられているバイト数を追跡​​するなどの手間が必要なため、他の利用可能なOutputStream実装を使用すると簡単な解決策があるのだろうかと思います。

など。どういうわけかBufferedOutputStreamの活用を考えましたが、うまくいかないと思います。基本的な考え方は別のOutputStreamを実装し、BufferedOutputStreamに255バイトの容量で渡し、満杯になったときにバッファをフラッシュするたびに新しいチャンクエントリを書き込むことでした。これはうまくいきません。BufferedOutputStreamは、あまりにも多くのバイトが(私のソースコードを理解している限り)一度に書き込まれると、バッファをもう使用しないためです。

+0

「リスト」を作成しないのはなぜですか? – Shadov

+0

'255バイトのチャンクのリストが必要です'を定義します。あなたが何を求めているのか不明です。 – EJP

+0

@EJP 'List '各バイトの[] 'エントリの長さは255です(最後のエントリは255バイト未満です)。 @Whatzsはい、ターゲットサーバと通信するフレームワークが後者を期待していなかった場合、Byte []の代わりに 'byte []'を使うことができました。 – fishbone

答えて

0

これは私が私の質問で提案したものの迅速な実装です。しかし、それはテストされていません。しかし、コードで使用する前にいくつかの具体的な変更を加えなければならず、変更を適用する前に共有すると思っていました。

public class ByteArrayListGeneratingOutputStream extends OutputStream 
{ 
    private byte[] buf; 
    private int off = 0; 
    private int size; 
    private List<byte[]> result = new ArrayList<byte[]>(); 

    public ByteArrayListGeneratingOutputStream(int size) 
    { 
     this.size = size; 
     buf = new byte[size]; 
    } 

    public List<byte[]> getResult() 
    { 
     return result; 
    } 

    @Override 
    public void write(int b) throws IOException 
    { 
     allocateBufferIfNeeded(); 
     buf[off++] = (byte) b; 
     flushBufferIfNeeded(); 
    } 

    @Override 
    public void write(byte buf[], int off, int len) throws IOException 
    { 
     if ((off < 0) || (off > buf.length) || (len < 0) || ((off + len) > buf.length) || ((off + len) < 0)) 
     { 
     throw new IndexOutOfBoundsException(); 
     } 
     while (len > 0) 
     { 
     allocateBufferIfNeeded(); 
     int effectiveLen = Math.min(len, size - this.off); 
     System.arraycopy(buf, off, this.buf, this.off, effectiveLen); 
     this.off += effectiveLen; 
     off += effectiveLen; 
     len -= effectiveLen; 
     flushBufferIfNeeded(); 
     } 
    } 

    private void flushBufferIfNeeded() throws IOException 
    { 
     if (off == size) 
     { 
     flush(); 
     } 
    } 

    private void allocateBufferIfNeeded() 
    { 
     if (buf == null) 
     { 
     buf = new byte[size]; 
     off = 0; 
     } 
    } 

    @Override 
    public void flush() throws IOException 
    { 
     if (off > 0) 
     { 
     result.add(buf); 
     off = 0; 
     buf = null; 
     } 
    } 

    @Override 
    public void close() throws IOException 
    { 
     flush(); 
    } 
} 
関連する問題