22

Javaでは、OutputStream(自分でそのストリームにデータを入力する)のコンテンツをByteBufferに入れる必要があります。簡単な方法でそれを行う方法は?

4

7 に答える 7

34

を作成して書き込み、を使用しByteArrayOutputStreamて内容を抽出できます。次に、出力バイト配列の内容を使用してを作成します。byte[]toByteArray()ByteBuffer.wrap(byte [])ByteBuffer

于 2010-04-26T21:02:45.553 に答える
25

@DJClayworthの答えのより効率的な変形があります。

@sehが正しく認識したように、バッキングオブジェクトのコピーByteArrayOutputStream.toByteArray()を返しますが、これは非効率的である可能性があります。ただし、バッキングオブジェクトとバイト数はどちらもクラスの保護されたメンバーです。したがって、ByteArrayOutputStreamの独自のバリアントを作成して、それらを直接公開できます。byte[]byte[]ByteArrayOutputStream

public class MyByteArrayOutputStream extends ByteArrayOutputStream {
  public MyByteArrayOutputStream() {
  }

  public MyByteArrayOutputStream(int size) {
    super(size);
  }

  public int getCount() {
    return count;
  }

  public byte[] getBuf() {
    return buf;
  }
}

このクラスの使用は簡単です。

MyByteArrayOutputStream out = new MyByteArrayOutputStream();
fillTheOutputStream(out);
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount());

その結果、すべての出力が書き込まれると、同じバッファーが入力ストリームのベースとして使用されます。

于 2013-03-28T16:05:05.790 に答える
6

上記の答えはあなたの問題を解決しますが、NIOに期待するようにそれらのどれも効率的ではありません。ByteArrayOutputStreamまたはMyByteArrayOutputStreamは、最初にデータをJavaヒープメモリに書き込み、次にそれをByteBufferにコピーします。これは、パフォーマンスに大きく影響します。

効率的な実装は、ByteBufferOutputStreamクラスを自分で作成することです。実際、それは非常に簡単です。write()メソッドを提供するだけです。ByteBufferInputStreamについては、このリンクを参照してください。

于 2014-05-09T17:39:19.080 に答える
1

OutputStreamの代わりにPipedOutputStreamを使用してみてください。次に、PipedInputStreamに接続して、PipedOutputStreamからデータを読み戻すことができます。

于 2010-04-26T20:53:24.903 に答える
1

あなたは自分でこのストリームに書いていると言いますか?もしそうなら、多分あなたはあなた自身のByteBufferOutputStreamを実装して、プラグアンドプレイをすることができます。

基本クラスは次のようになります。

public class ByteBufferOutputStream extends OutputStream {
    //protected WritableByteChannel wbc; //if you need to write directly to a channel
    protected static int bs = 2 * 1024 * 1024; //2MB buffer size, change as needed
    protected ByteBuffer bb = ByteBuffer.allocate(bs);

    public ByteBufferOutputStream(...) {
        //wbc = ... //again for writing to a channel
    }

    @Override
    public void write(int i) throws IOException {
        if (!bb.hasRemaining()) flush();
        byte b = (byte) i;
        bb.put(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        if (bb.remaining() < len) flush();
        bb.put(b, off, len);
    }

    /* do something with the buffer when it's full (perhaps write to channel?)
    @Override
    public void flush() throws IOException {
        bb.flip();
        wbc.write(bb);
        bb.clear();
    }

    @Override
    public void close() throws IOException {
        flush();
        wbc.close();
    }
    /*
}
于 2018-11-06T11:45:10.783 に答える
1

//保護されたメンバーbufにアクセスし、extendクラスからカウントします

class ByteArrayOutputStream2ByteBuffer extends ByteArrayOutputStream {
    public ByteBuffer toByteBuffer() {
        return ByteBuffer.wrap(buf, 0, count);
    }
}
于 2020-03-30T06:59:16.073 に答える
0

動的な再割り当てによるByteBuffer支援の効率的な実装を参照してください。OutputStream

/**
 * Wraps a {@link ByteBuffer} so it can be used like an {@link OutputStream}. This is similar to a
 * {@link java.io.ByteArrayOutputStream}, just that this uses a {@code ByteBuffer} instead of a
 * {@code byte[]} as internal storage.
 */
public class ByteBufferOutputStream extends OutputStream {

    private ByteBuffer wrappedBuffer;
    private final boolean autoEnlarge;

https://gist.github.com/hoijui/7fe8a6d31b20ae7af945

于 2022-01-29T18:39:09.333 に答える