04. buffer 클래스가 제공하는 유틸리티 메소드
이번 단에서는 버퍼 계열의 부모 클래스인 Buffer 클래스에 대해 살펴보자. 버퍼 클래스는 유용한 유틸리티 메소드를 많이 가지고 있다.
1. clear() 메소드
ByteBuffer buf = ByteBuffer.allocate(10);
...
buf.clear();
이처럼 clear() 메소드를 호출하게 되면 position, limit, mark 값의 속성들이 버퍼가 생성될 떄 초기값으로 초기화 된다.
2. rewind() 메소드
ByteBuffer buf = ByteBuffer.allocate(10); … buf.rewind();
rewind() 메소드를 호출하면 position 속성값만 초기화 된다. rewind()역시 clear처럼 호출전에 mark값이 설정되어 있었다면 초기값인 -1로 초기화된다.
3. flip() 메소드
ByteBuffer buf = ByteBuffer.allocate(10);
...
buf.flip();
이 메소드는 limit를 position이 있던 위치로 설정한 후에 position을 0으로 이동시킨다. 이 메소드 역시 flip()을 호출하기 전 mark 값이 설정되어 있었다면 mark 값 역시 -1로 초기화 시킨다.
이미 사용했던 버퍼를 재사용하기 위해 버퍼의 clear() 메소드를 호출하고 데이터를 버퍼에 쓸것이다. 그리고 flip() 메소드로 재사용할 범위를 지정한 후 버퍼에서 데이터를 읽으면 된다.
# 05. Buffer 하위 클래스 유틸리티 메소드
### 1. compact() 메소드
ByteBuffer buf = ByteBuffer.allocate(10); … buf.compact();
position과 limit 사이에 남아있는 데이터를 버퍼의 맨 앞에부터 순서대로 덮어 쓴다. 쓴 위치만큼 position을 이동시키고 limit는 capacity와 동일하게 만든다. 또한 compact() 메소드 호출 전에 mark가 설정되어 있었다면 mark 값 역시 -1로 초기화 한다.
이처럼 compact() 메소드는 버퍼 안의 데이터를 남김없이 모두 전송하고 싶을 떄 유용하게 사용할 수 있다.
in 채널에서 읽은 데이터를 out 채널로 보낼 떄 버퍼의 데이터를 모두 전송하기 위해 compact() 메소드를 사용한 템플릿 코드이다.
buf.clear(); // 읽을 데이터가 있으면 채널에서 버퍼로 데이터를 읽어들인다. while(in.read(buf) > 0 && buf.hasRemaining()) { buf.flip(); // 버퍼로 읽어들인 데이터를 채널에 전송한다. out.write(buf); // 전송하지 못한 데이터가 있으면 버퍼의 맨 앞부분으로 모두 복사해서 다음 번에 재전송 되게 한다. buf.compact(); }
### 2. duplicate() 메소드
duplicate() 메소드는 버퍼에 복사본을 생성할 떄 사용하는 메소드다. 복사본이라고 했지만 데이터와 기본 속성들을 모두 복사한 새로운 버퍼를 생성하진 않고 단지 원본 버퍼와 같은 메모리 공간을 참조하는 버퍼를 생성한다.
자료형의 속성만 참조할 뿐 position, limit, capactiy는 각자 관리한다.
### 3. asReadOnlyBuffer() 메소드
asReadOnlyBuffer() 메소드로 생성된 읽기전용 버퍼는 앞서 살펴본 duplicate() 메소드로 생성된 버퍼와 한가지를 제외하곤 동일하다.
duplicate() 메소드로 생성된 버퍼는 put() 메소드의 호출로 데이터를 수정할 수 있다. 하지만 ReadOnly라는 이름처럼 오직 읽기만 가능하다.
### 4. slice() 메소드
duplicate(), asReadOnlyBuffer() 메소드로 생성된 버퍼들이 원본과 동일한 크기를 갖는 복사본을 생성하는 것이다. 반면 slice()는 버퍼의 일부분만을 복사하는 메소드다. slice()를 호출하면 원본 버퍼의 position 에서 limit까지만을 떼어내서 생성한다. 이렇게 생성된 버퍼 역시 자신만의 네가지 기본 속성을 갖고 원본 버퍼와 동일한 메모리 주소를 참조한다. 하지만 앞의 duplicate(), asReadOnlyBuffer와 달리 slice로 생성된 buffer는 각각의 기본 속성이 초기화 된다.
출처 : 김성박 송지훈 공저, 『 자바 IO & NIO 네트워크 프로그래밍』, 한빛미디어(2004.9.30), 13장 인용