Tistory View

Java의 stream은 워낙 쓸일이 많기에 이런 저런 stream들이 많다. 그 중 byte[]와 가장 관련이 많은 ByteBuffer를 stream으로 변환을 하려면 InputStream, OutputStream의 몇가지 함수만 Override하면 사용할 수가 있다.

 

그리 어렵지도 않은 작업일 줄이라..(Java의 Stream을 필자는 너무 싫어해서..)

 

OutputStream

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

public class ByteBufferOutputStream extends OutputStream {
    private ByteBuffer mBuffer;

    public ByteBufferOutputStream(ByteBuffer buffer) {
        mBuffer = buffer;
    }

    public void close() throws IOException {
        mBuffer = null;
    }

    private void ensureStreamAvailable() throws IOException {
        if (mBuffer == null) {
            throw new IOException("buffer is null");
        }
    }

    @Override
    public void write(int b) throws IOException {
        this.ensureStreamAvailable();
        mBuffer.put((byte) b);
    }

    @Override
    public void write( byte[] bytes) throws IOException {
        this.write(bytes, 0, bytes.length);
    }


    @Override
    public void write( byte[] bytes, int off, int len) throws IOException {
        this.ensureStreamAvailable();

        if ((off < 0) || (off > bytes.length) || (len < 0) ||
                ((off + len) > bytes.length) || ((off + len) < 0))
        {
            throw new IndexOutOfBoundsException();
        }

        if (len == 0) {
            return;
        }

        mBuffer.put(bytes, off, len);
    }
}

 

InputStream

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class ByteBufferInputStream extends InputStream
{
    private ByteBuffer mBuffer;

    public ByteBufferInputStream( ByteBuffer buffer ) {
        mBuffer = buffer;
    }

    public void close() {
        mBuffer = null;
    }

    private void ensureStreamAvailable() throws IOException {
        if (this.mBuffer == null) {
            throw new IOException("read on a closed InputStream!");
        }
    }

    @Override
    public int read() throws IOException {
        this.ensureStreamAvailable();
        return mBuffer.hasRemaining() ? mBuffer.get() & 0xFF : -1;
    }

    @Override
    public int read( byte[] buffer) throws IOException {
        return this.read(buffer, 0, buffer.length);
    }

    @Override
    public int read(byte[] buffer, int offset, int length) throws IOException {
        this.ensureStreamAvailable();
        if ( !( offset >= 0 && length >= 0 && length <= buffer.length - offset ) ) {
            throw new IndexOutOfBoundsException();
        }

        if (length == 0) {
            return 0;
        }

        int remainingSize = Math.min( mBuffer.remaining(), length);
        if (remainingSize == 0) {
            return -1;
        }

        mBuffer.get(buffer, offset, remainingSize);
        return remainingSize;
    }

    public long skip(long n) throws IOException {
        this.ensureStreamAvailable();
        if (n <= 0L) {
            return 0L;
        }
        int length = (int) n;
        int remainingSize = Math.min( mBuffer.remaining(), length );
        mBuffer.position(mBuffer.position() + remainingSize);
        return (long)length;
    }

    public int available() throws IOException {
        this.ensureStreamAvailable();
        return mBuffer.remaining();
    }

}

 

다음의 파일을 받아 압축을 풀고, package에 따른 디렉토리에 넣고, package이름을 수정하여 사용하면 된다.

ByteBufferStreams.zip
0.00MB

 

 

ByteBuffer의 크기가 정해져 버린다는 단점으로 인해 전체 크기를 할당하고 써야하는 문제가 있지만, ByteBuffer의 flip, compat, clear를 잘 이용하면 계속 쓸수도 있기는 하다. 실제 사용하려면 좀 짜증이 나니, 그냥 전체를 할당하는 식으로 사용하는 것이 속편하다.

 

ByteBuffer의 flip, compat..등등의 사용법은 다음에 링크해 둔다.

 

jamssoft.tistory.com/221

 

Buffer(ByteBuffer, CharBuffer...) flip, compact, clear사용법

소스코드 ByteBuffer, IntBuffer, FloatBuffer, DoubleBuffer, ShortBuffer, LongBuffer, CharBuffer.. 등에는 flip, compact, clear등에 함수가 있다. 근데, 이 flip, compact, clear는 도대체가 뭐 하는 녀석인..

jamssoft.tistory.com

 

 

 

Reference

까먹었다..

Replies
Reply Write