2009-03-08 1 views
1

java.nio.ByteBuffer를 통해 UTF8 문자열을 읽으려고합니다. 크기는 unsinged int이며, 물론 Java에는 없습니다. 나는 그 가치를 오래도록 가치를 읽었습니다.길이가 부호없는 int 인 ByteBuffer에서 UTF-8 문자열 읽기

내가 가지고있는 다음 문제는 long 배열을 만들 수 없다는 것이며, long으로 int 형으로 다시 캐스팅하면 서명 될 것입니다.

또한 limit() 버퍼를 사용하여 시도했지만 다시 int int 함께 작동합니다.

내가하고있는 특정 일은 클래스 파일에서 UTF8 문자열을 읽는 것이므로 버퍼에 UTF8 문자열이 더 많이 포함되어 있습니다.

ByteBuffer에서 잠재적 인 부호없는 int 길이를 가진 UTF8 문자열을 읽는 방법에 대한 아이디어.

편집 :

Here is an example of the issue.

SourceDebugExtension_attribute { 
     u2 attribute_name_index; 
     u4 attribute_length; 
     u1 debug_extension[attribute_length]; 
    } 

attribute_name_index 
    The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "SourceDebugExtension". 

attribute_length 
    The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus the number of bytes in the debug_extension[] item. 

debug_extension[] 
    The debug_extension array holds a string, which must be in UTF-8 format. There is no terminating zero byte. 

    The string in the debug_extension item will be interpreted as extended debugging information. The content of this string has no semantic effect on the Java Virtual Machine. 

그래서, 기술적 인 관점에서, 길이 (4 바이트 부호) 전체 U4 인 클래스 파일에 문자열을 가질 수 있습니다.

UTF8 문자열의 크기에 제한이 있다면 문제가되지 않습니다 (저는 UTF8 전문가가 아니기 때문에 그러한 제한이있을 수 있습니다).

난 그냥에 리면 그 긴 문자열이있을 것되지 않는 현실에 갈 수 ...

답변

6

바이트의 배열 2GB의 (자바의 가장 큰 양의 값보다 더 많은 경우를 제외하고 int) long을 다시으로 전송하는 데 문제가 없습니다. 바이트 배열의 길이가 2GB보다 더 할 필요가있는 경우, 당신이없는 이상 그는 JVM의 기본 최대 힙 크기보다 훨씬 더 때문에 ...

+1

인코딩이 1 바이트/문자보다 큰 경우는, 확실히 바이트 배열이 길어질 가능성이 있습니다. String는 byte [] 배열이 아니라 char [] 배열을 캡슐화합니다. –

+0

확신 할 수 있습니다. 그래도 2GB를 치지는 못할 것입니다. – Alnitak

+0

내 편집을 참조하십시오 ... 크기가 전혀 내 통제하에 있지 않습니다 ... – TofuBeer

1

, 잘못하고있는

은 INT의 원을 체결 데 당신의 주요 문제가되지 않습니다. 길이가 40 억에 달하는 String이 있다고 가정 해보십시오. 최소한 4GB 인 ByteBuffer와 4GB 이상의 byte []가 필요합니다. 이것을 String으로 변환 할 때는 적어도 8GB (문자 당 2 바이트)와 StringBuilder가 필요합니다. (적어도 8GB 이상) 1 String을 처리하려면 24 GB가 필요합니다. 비록 당신이 많은 기억을 가지고 있더라도 당신은이 크기의 많은 문자열을 얻지 못할 것입니다.

또 다른 접근법은 어떤 경우에도 String을 처리 할 메모리가 충분하지 않기 때문에 부호있는 길이로 취급하고 서명되지 않은 경우는 오류로 처리하는 것입니다. 길이가 20 억 (2^31-1) 인 String을 처리하는 경우에도이 방법으로 String으로 변환하려면 12GB가 필요합니다.

1

자바 배열 (즉, 자바 서명)을을 사용하여 액세스 as per the languge spec에 대한 INT를, 그래서 그것은 문자열 (char 배열에 의해 뒷받침되는)

을 Integer.MAX_INT

보다 긴하지만 심지어 많은 방법이 불가능하다 하나의 덩어리에서 처리하기에는 너무 많습니다. 충분히 큰 String이 발생하면 대부분의 컴퓨터에서 OutOfMemoryError를 사용하여 성능을 완전히 떨어 뜨리고 프로그램이 실패하게됩니다.

당신이해야 할 일은 모든 문자열을 합리적인 크기로 처리하는 것입니다 (한 번에 몇 메가). 그러면 처리 할 수있는 크기에는 실제적인 제한이 없습니다.

0

ByteBuffer 위에 CharSequence을 구현할 수 있다고 생각합니다. 문자를 다루는 대부분의 유틸리티는 실제로 String을 기대하지만, "String"이 힙을 따라 가지 않도록 할 수 있습니다. 그리고 심지어 실제로는 CharSequence에 대한 제한이 있습니다. 크기가 int로 반환 될 것으로 예상합니다.

(이론적으로 크기를 long으로 반환하는 CharSequence의 새 버전을 만들 수 있지만 해당 CharSequence를 처리하는 데 도움이되는 Java에는 아무 것도 없습니다. subSequence(...)을 구현하면 유용 할 수 있습니다. 보통의 CharSequence).