2014-04-22 1 views
1

바이트 버퍼를 가지고 있고 Ints, Chars 등을 넣습니다. 얼마나 많은 공간이 필요한지 알지 못하기 때문에 바이트 버퍼를 동적으로 증가시키고 싶습니다. 어떻게 할 수 있습니까?바이트 버퍼의 할당 된 메모리를 확장하는 방법

예 : - 난 2 바이트 의 ByteBuffer를 가지고 - 나는의 ByteBuffer (ByteBuffer를 지금 가득) 에 문자를 추가 - 나는 4 바이트로의 ByteBuffer를 확장하여의 ByteBuffer에 정수를 추가. 시작시 6 바이트로 바이트 버퍼를 할당 할 수 없습니다.

ByteBuffer byteBuffer = ByteBuffer.allocate(2); 

    byteBuffer.putChar('a'); 
    byteBuffer.putInt(1); 

나는 많은 사람들이 몇 분 오래 내 질문에서 작업하는 방법에 대한 매우 감동입니다. 모두에게 고맙습니다. 또한 훌륭한 Plattform 인 Stackoverflow에도 감사드립니다.

여러분 모두가 물었습니다. 그래서 여기에서 설명하려고합니다. 내 용도 : DB에 저장하고 읽고 싶습니다 javaobjects (javaclasses)로 표시된 데이터를 구조화했습니다. 독서는 매우 빨라야합니다. 내가 지금까지했던 어떤 :

  • 자바 직렬화 및 역 직렬화하고 BLOB에 저장 -> 잘하지만 너무 느리게 작동합니다.

  • kryo와 같은 제 3 자 시리얼 라이저 (매우 좋은)를 시도했지만, 내 케이스 (안드로이드)에서는 사용할 수 없습니다.

나의 새로운 전략 :-)

: 나는 내 수업 내 자신의 외부화을한다. 그게 내 클래스의 전체 데이터를 바이트 배열로 구성하고 싶습니다. 느려질 수 있습니다. 그런 다음 bytearray를 데이터베이스에 저장합니다. 독서를 할 때 나는 bytearray를 한 번에 읽고 싶습니다 (bytearray는 약 10k입니다). (나는 그들을 많이 가질 것이다). 그런 다음 구조화 된 데이터를 추출하기 위해 bytearray를 파싱합니다.

putb와 readX와 같은 메소드 때문에 bytebuffer를 사용하는 것이 이상적이라고 생각했습니다. (X, chars, floats, int)

+1

왜 다른 데이터 구조를 사용하지 않습니까? 동적 재 할당을 원하면 링크 된 목록을 사용하지 않는 이유는 무엇입니까? – John

+0

용량이 4 또는 1024 바이트 또는 1MB 인 ByteBuffer를 할당 할 수없는 이유는 무엇입니까? –

+0

BTW putChar()는 자주 사용되지 않기 때문에 왜 이렇게하는지에 따라 문자를 쓰는 것이 더 좋습니다. –

답변

0

수 없습니다. 이는 의도적으로 설계된 동작입니다. 새 바이트 버퍼를 할당하고 그 위에 넘치는 데이터를 쓸 수 있습니다. ByteBuffers를 LinkedList (필요에 따라 커질 것입니다)에 보관할 수 있으며 새 항목을 할당하기 위해 메모리가 부족할 경우 ByteBuffers를 디스크로 스풀링 할 수도 있습니다. 각 ByteBuffer가 같은 크기이면 사소한 방정식을 통해 하나의 버퍼가있는 것처럼 액세스 할 수 있지만 슬라이싱 또는 압축을 사용하지 못하게하거나 또는 그 중 하나를 사용하여 수행 할 수있는 멋진 작업을 수행 할 수 없게됩니다. :)

하지만 사람들이 반복해서 말한 것처럼, 그것은 당신이 필요로하는 것에 달려 있습니다.

+0

제가하려고하는 것을 설명하기 위해 제 질문을 연장했습니다. –

+0

솔루션을 제공하지 않습니다. 왜 ? – Alex

+0

무슨 뜻인지 모르겠다. –

1

IMHO 가장 좋은 대답은 처음부터 충분한 공간이 있는지 확인하는 것입니다. ByteBuffer를 동적으로 크기를 재조정하는 것은 매우 비싸고 속도가 훨씬 느립니다. 문자에 사용하는

ByteBuffer byteBuffer = ByteBuffer.allocate(6 /* or more */); 

byteBuffer.putChar('a'); 
byteBuffer.putInt(1); 

간단한 버퍼의 StringBuilder입니다.

StringBuilder sb = new StringBuilder(); 
sb.append('a'); 
sb.append('b'); 
당신이 당신의 마지막 문 다음에 새로운 문자를 추가하는 방법

? 작업이 완료 만

sb.append('n'); 

. 당신이의 ByteBuffer에 추가 (및 문자를 사용하지 않는) 경우

// if you need a ByteBuffer 
ByteBuffer bb = ByteBuffer.wrap(sb.toString().getBytes(StandardCharsets.UTF_8)); 
// bb will have two bytes for 'a' and 'b' 

그러나, 나는 당신이 이제까지 필요한 것보다 더 큰 버퍼를 만드는 제안 따라서 당신은 크기를 조정할 필요가 없습니다. 힙 사용에 대한 우려가있는 경우 힙을 대신 사용할 수 있습니다.

// uses about 48 bytes of heap. 
ByteBuffer bb = ByteBuffer.allocateDirect(1024*1024); 

bb.putInt(1234); 
bb.putDouble(1.111); 
bb.putLong(12345678987654321L); 
+0

+1 역동적 인 재 할당이 가능하므로 훨씬 더 좋은 해결책입니다. – John

+0

그게 아니라 soultion. 마지막 성명서 뒤에 어떻게 새로운 성격을 추가 하시겠습니까? –

+0

@ user1344545 답변에 다른 문자를 추가했습니다. –

1

바이트 버퍼를 사용할 때의 문제는 고정 크기로 시작한다는 것입니다. 보류하려는 데이터의 양을 알면 매우 좋습니다. 예를 들어, 입력을 읽고 12 바이트 만 읽으려는 경우 12 바이트 배열 만 작성하십시오.

  1. 당신은 빠른 속도를 필요로한다면, 단지 기반으로 큰 배열을 할당 : 당신은 당신이 byte 버퍼에해야 할 것 얼마나 많은 데이터를 알 수없는 경우

    , 당신은이 일을 할 수있다 얼마나 많은 데이터가 필요한지에 대한 예측. 예를 들어, 큰 파일을 읽었을 때 빠른 속도로 읽으 려한다면 매우 큰 바이트 버퍼 (파일 크기에 따라 2MB 정도)를 사용해야합니다.

  2. 동적 할당을 사용하는 구조체를 사용하십시오. 이것은 훨씬 더 나은 해결책이지만 속도가 느립니다. 매우 큰 배열을 할당하면 매우 느려지지만 메모리를 낭비하지는 않습니다. 바이트 버퍼를 사용하여 512KB를 할당했지만 1KB 만 사용하면 낭비되는 공간입니다! 동적으로 할당 된 구조 (LinkedList의, 스택, 큐, 나무)를 사용하면 추가하고

가 메모리를 많이 낭비뿐만 아니라 때문에 전혀 사용하지 않는 것이 좋습니다 최종 솔루션을 필요로하는 요소를 제거 할 수 있습니다, 그것은 또한 천천히 진행됩니다. 필요한만큼의 공간을 바이트 버퍼에 할당 한 다음 더 많은 메모리가 필요할 때 새 버퍼를 만들고 데이터를 복사 할 수 있습니다. 이것은 당신이하려는 일이며 매우 비효율적입니다.

내 opionion에서 Peter Lawrey의 대답은 StringBuilder에서 바이트 배열로 쉽게 이동할 수 있기 때문에이 문제에 대한 대단한 해결책입니다. 이것은 당신이 필요로하는 모든 효율성과 속도를 가지고 있습니다.

+1

+1 BTW는 2 바이트의 byte []와 6 바이트의 byte []는 같은 양의 메모리를 사용합니다 (64 비트 JVM). 당신은 6 대신 크기 2를 만들어 아무것도 저장하지 않습니다. –

0

나는 나의 유스 케이스에 대한 해결책을 찾았는데, 여기서 간단히 설명하고자한다. 나는 Mikkel의 대답을 받아 들였습니다. 질문에 관해서는 옳은 대답인데, John이 멘토링했기 때문입니다. 또한 베드로에게 내가 배울 수있는 훌륭한 설명에 감사한다.

나는 내 상황에 편리한 DataInputStream을 사용합니다. DataInputStream과 putInt, PutBoolean, PutString과 같은 편리한 메소드를 사용하여 JavaBject를 기반으로 데이터 스트림을 만듭니다. 그런 다음 DataInputStream의 binaryarray를 db로 blob로 저장합니다.

정확히 읽는 것은 DataInputStream의 반대입니다.

이렇게하면 javaobejects의 javadeserialization과 비교하여 객체를 읽을 때 성능이 500 % 향상되고 저장 공간 사용량이 25 % 감소합니다.

관련 문제