Akashic Records

자바 nio - 6 본문

오래된글/Java

자바 nio - 6

Andrew's Akashic Records 2018. 4. 9. 11:25
728x90

6. ByteBuffer 클래스

우선 api문서에 있는 ByteBuffer 클래스의 선언은 다음과 같다.


public abstract class ByteBuffer extends Buffer implements Comparable


선언부분을 보면 ByteBuffer 클래스는 Buffer 클래스를 상속하고 Comparable 인터페이스를 구현하고 있다. Buffer 클래스를 상속는 누누히 말해 온 것이고 Comparable 인터페이스를 구현한다는 것은 ByteBuffer 클래스가 compareTo()라는 메서드를 가지고 있기 때문이다. 이는 다른 Buffer 클래스의 하위 클래스도 다 마찬가지이다.

ByteBuffer 클래스의 특징은 다음과 같이 두가지로 들수 있다.

  1. Direct Buffer를 만들 수 있다.

  2. 다른 유형의 버퍼로 변환이 가능하다.

이는 사실 하나로 생각될 수 있는데 그것은 ByteBuffer 클래스가 Direct Buffer를 만들면 이 Direct Buffer를 다른 유형으로 변환해서 쓸 수 있기 때문이다.


1. ByteBuffer 클래스 추가 메서드

- public static ByteBuffer allocateDirect(int capacity)

: Direct Buffer를 생성한다. Direct Buffer는 자바가 제공하는 Heap 메모리를 쓰지 않고 운영체제가 제공하는 메모리를 사용하므로 만들때에는 시간이 걸린다. 하지만 입출력 속도가 매우 빠른 장점을 가지고 있다. 따라서 Direct Buffer는 대용량의 데이터를 다루고 오랜 기간동안 쓰면서 빠른속도가 필요한 곳에 적합하다. 또 다른 장점으로는 JNI를 통해 직접 접근이 가능하다. JNI는 native 코드이므로 Direct Buffer를 navtive 코드에 쓰거나 native 에서 수정한 코드를 자바에서 쓰는 것이 가능하다.

- 다른 유형으로 변환시키는 메서드 -> asXXXBuffer()

public abstract CharBuffer asCharBuffer()

public abstract DoubleBuffer asDoubleBuffer()

public abstract FloatBuffer asFloatBuffer()

public abstract IntBuffer asIntBuffer()

public abstract LongBuffer asLongBuffer()

public abstract ShortBuffer asShortBuffer()

이들 메서드로 변환된 ByteBuffer는 변환유형에 맞는 Buffer로서의 기능을 할 수 있게 된다.

- public final ByteOrder order()

: 해당 버퍼의 ByteOrder를 리턴

- public final ByteBuffer order(ByteOrder bo)

: 인자로 들어온 ByteOrder로 버퍼를 설정한다. 인자로는 바이트 순서인 BIG_ENDIAN 또는 LITTLE_ENDIAN 이 온다.

: 다른 클래스에서도 ByteOrder(바이트 순서)를 변경할 수 있는데, 이는 직접 변경할 수는 없고 ByteBuffer클래스에서 바꾼 다음 이른 변환해야 한다.

- getXXX()/putXXX()

: ByteBuffer는 여러 유형의 데이터를 put/get 할 수 있는 메서드가 있다. put/get 뒤에 해당 데이터형만 적으면 된다. 이는 ByteBuffer가 다른 유형의 버퍼로 전환될 수 있는 능력을 가지고 있기 때문이다. 예를 들어 다음과 같이 사용한다.

buf1.putChar('가');

buf1.putDouble(3.14);

buf1.putFloat(3.14f);

이를 다음과 같이 호출해도 상관없다.

buf1.putChar('가').putDouble(3.14).putFloat((float)3.14);

- public int compareTo(Object ob)

: 인자로 들어온 객체 ob와 비교해서 결과 값을 리턴해 준다. 이때 리턴값이 음수면 객체 ob보다 자신이 작다는 뜻이고, 0은 같다는 뜻, 양수는 객체 ob보다 자신이 크다는 뜻이다. 주의할 점은 반드시 유형이 같은 버퍼끼리 비교해야 한다.


2. 예제


package nio;

import java.nio.*;

import java.nio.ByteBuffer;

public class ByteBufferTest {

private StringBuffer log = null;


public static void main(String[] args) {

ByteBufferTest test = new ByteBufferTest();

test.exec();

}


public void log(String message) {

if(log == null)

log = new StringBuffer();

log.append(message+"\n");

}


public void print() {

System.out.println(log);

}


public void exec() {

ByteBuffer buf_1 = createByteBuffer(25);

buf_1.putChar('A');

buf_1.putDouble(3.14);

buf_1.putFloat((float)3.14);


log("buf_1 Clear Before : " + buf_1);


buf_1.clear();


log("buf_1 Clear After : " + buf_1);

log(buf_1.getChar()+"");

log(buf_1.getDouble()+"");

log(buf_1.getFloat()+"");


ByteBuffer buf_2 = createByteBuffer(20);

for (int i = 1;i <= 5;i++) {

buf_2.putInt(i);

}


log("buf_2 Clear Before: " + buf_2);


buf_2.clear();


log("buf_2 Clear After : " + buf_2);

IntBuffer intbuf = buf_2.asIntBuffer();


log("IntBuffer :" + intbuf);


while (intbuf.hasRemaining()) {

log(intbuf.get()+"");

}

print();

}

ByteBuffer createByteBuffer(int capacity) {

return ByteBuffer.allocate(capacity);

}

}


<< 실행 결과 >>


C\>java ByteBufferTest

buf_1 Clear Before : java.nio.HeapByteBuffer[pos=14 lim=25 cap=25]

buf_1 Clear After : java.nio.HeapByteBuffer[pos=0 lim=25 cap=25]

A

3.14

3.14

buf_2 Clear Before: java.nio.HeapByteBuffer[pos=20 lim=20 cap=20]

buf_2 Clear After : java.nio.HeapByteBuffer[pos=0 lim=20 cap=20]

IntBuffer :java.nio.ByteBufferAsIntBufferB[pos=0 lim=5 cap=5]

1

2

3

4

5


소스를 보면 ByteBuffer 를 생성하고 이것의 ByteOrder를 출력해보니 BIG_ENDIAN임을 확인할 수 있다. 이것은 운영체계와 별개의 값이다. 자바가상머신은 하나의 독립된 컴퓨터이기 때문이다. 그리고 char,double,float 형의 데이터를 putXXX()메서드로 넣고 있다. 그리고 나서 다시 get을 해서 출력한다.

다시 크기가 20인 바이트 버퍼를 생성하고 이번에는 int형의 데이터를 삽입했다. 그리고 나서 버퍼의 위치를 clear()메서드로 0으로 만들고 나서 ByteBuffer를 IntBuffer로 변환한다. 변환하기전에 반드시 버퍼의 위치를 0으로 만들주어야 한다. 그이유는 변환시 버퍼의 현재 위치부터 변환이 시작되기 때문이다. 변환된 객체 intbuf를 출력하면 position는 0이 되고 limit와 capacity가 5으로 바뀐것을 볼 수 있다. 이는 IntBuffer로 변환되면서 데이터 크기를 int형의 크기로 바꾸어 버리기 때문이다. 즉 총 크기가 20이니 int는 4바이트를 차지하니깐 이를 나누면 5이 나온다. 하지만 데이터는 int형이 아니라서 그 크기에 맞게 들어간 것이 보인다.


728x90

'오래된글 > Java' 카테고리의 다른 글

자바 nio - 8  (0) 2018.04.09
자바 nio - 7  (0) 2018.04.09
자바 nio - 5  (0) 2018.04.09
자바 nio - 4  (0) 2018.04.09
자바 nio - 3  (0) 2018.04.09
Comments