2016-11-05 4 views
0

Я пытался преобразовать ByteBuffer в String и наоборот. вручную, я отлажена мой код, чтобы получить состояние ByteBuffer перед преобразованием его в строку и после, а также:Преобразование ByteBuffer в String и Vice vera - изменение в структуре ByteBuffer

Так что мой HashMap где хранить ByteBuffer выглядит примерно так:

0 = {[email protected]} "studentId" -> "{S: ER3478CT2016,}" 
1 = {[email protected]} "collegeId" -> "{S: 123456,}" 
2 = {[email protected]} "changeField1" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=424 cap=424],}" 
3 = {[email protected]} "studentAddress" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=64 cap=64],}" 
4 = {[email protected]} "studentName" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=32 cap=32],}" 
5 = {[email protected]} "studentTerm" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=32 cap=32],}" 

Но когда я преобразовать его в строку и обратно к ByteBuffer, я вижу следующее изменение:

0 = {[email protected]} "studentId" -> "{S: ER3478CT2016,}" 
1 = {[email protected]} "collegeId" -> "{S: 123456,}" 
2 = {[email protected]} "changeField1" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=422 cap=466],}" 
3 = {[email protected]} "studentAddress" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=121 cap=121],}" 
4 = {[email protected]} "studentName" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=56 cap=72],}" 
5 = {[email protected]} "studentTerm" -> "{B: java.nio.HeapByteBuffer[pos=0 lim=42 cap=78],}" 

так, как я конвертировать мой ByteBuffer в строку является:

ByteBuffer buffer = map.get("changeField1"); 
String myValue = new String(buffer.array(), "UTF-8"); 

Кроме того, способ преобразовать строку обратно в ByteBuffer выглядит следующим образом:

ByteBuffer buffer = CharSet.forName("UTF-8").encode(myValue); 

Почему изменение в пределах значений и капитализацией, когда строка преобразуется обратно в ByteBuffer? Я думал, так как я не знаю кодировку ByteBuffer, и я использую UTF-8 для кодирования его в String, что может быть причиной? Это правильно или есть более эффективный способ преобразования byteBuffers в строки и наоборот?

+0

Является 'String myValue = new String (changeField.array()," UTF-8 ");' на самом деле предполагается, что это 'String myValue = new String (buffer.array()," UTF-8 "); ? Не могли бы вы изменить? –

+0

Если вы снова конвертируете его в строку, какие строки у вас есть в начале и в конце? – lexicore

+0

@lexicore: струны в порядке. Я нигде не изменяю нити. Я храню строки как таковые. Вы говорите мне снова преобразовать полученный byteBuffer в строку и посмотреть, что является результатом? – chrisrhyno2003

ответ

0

Вот фрагмент реализации для Charset.encode() метода

int n = (int)(in.remaining() * averageBytesPerChar()); 
ByteBuffer out = ByteBuffer.allocate(n); 

Как вы можете видеть, емкость буфера не соответствие один к одному к входу in, а на основе другого фактор, возвращаемый averageBytesPerChar(), поэтому размер буфера немного больше. Вот полная реализация Charset.encode()

public final ByteBuffer encode(CharBuffer in) throws CharacterCodingException 
    { 
     int n = (int)(in.remaining() * averageBytesPerChar()); 
     ByteBuffer out = ByteBuffer.allocate(n); 

     if ((n == 0) && (in.remaining() == 0)) 
      return out; 
     reset(); 
     for (;;) { 
      CoderResult cr = in.hasRemaining() ? 
       encode(in, out, true) : CoderResult.UNDERFLOW; 
      if (cr.isUnderflow()) 
       cr = flush(out); 

      if (cr.isUnderflow()) 
       break; 
      if (cr.isOverflow()) { 
       n = 2*n + 1; // Ensure progress; n might be 0! 
       ByteBuffer o = ByteBuffer.allocate(n); 
       out.flip(); 
       o.put(out); 
       out = o; 
       continue; 
      } 
      cr.throwException(); 
     } 
     out.flip(); 
     return out; 
    } 
+0

Прошу прощения, но я немного смущен. Является ли это реальным ответом на изменение моего подхода? Или это говорит мне то место, где я ошибаюсь? – chrisrhyno2003

+0

Разница, которую вы получаете, связана с реализацией метода, который был тем, что я пытался преодолеть. – Dummy

0

подозрение у меня есть, что ByteBuffer.array() на самом деле дает вам весь массив байт который создает буфер - не только часть заполнена. ByteBuffer.array() не учитывает limit. Таким образом, ваша строка может содержать другие символы, построенные из байтов массива байтовых байт.

+0

После того, как вы упомянули об этом, я изменил код, чтобы выглядеть примерно так: ByteBuffer buffer = map.get ("changeField1"); байт [] ba = новый байт [buffer.limit()]; buffer.get (ba); String myValue = новая строка (ba, "UTF-8"); Все те же ошибки/изменения в пределах. – chrisrhyno2003

+0

@ chrisrhyno2003 Так что же в буфере? Побайтно? – lexicore

+0

Ах, ничего. Постепенно это был единственный аргумент, который я мог придумать. Но в остальном это не имеет большого значения, я полагаю. – chrisrhyno2003