ByteBuffer отсутствует данные при декодировании в виде строки - PullRequest
0 голосов
/ 13 декабря 2018

Я читаю и пишу в ByteBuffer

import org.assertj.core.api.Assertions;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

public class Solution{
public static void main(String[] args) throws Exception{

    final CharsetEncoder messageEncoder = Charset.forName("ISO-8859-1").newEncoder();
    String message = "TRANSACTION IGNORED";
    String carrierName= "CARR00AB";
    int messageLength = message.length()+carrierName.length()+8;


    System.out.println(" --------Fill data---------");
    ByteBuffer messageBuffer = ByteBuffer.allocate(4096);
    messageBuffer.order(ByteOrder.BIG_ENDIAN);
    messageBuffer.putInt(messageLength);
    messageBuffer.put(messageEncoder.encode(CharBuffer.wrap(carrierName)));
    messageBuffer.put(messageEncoder.encode(CharBuffer.wrap(message)));
    messageBuffer.put((byte) 0x2b);
    messageBuffer.flip();

    System.out.println("------------Extract Data Approach 1--------");

    CharsetDecoder messageDecoder = Charset.forName("ISO-8859-1").newDecoder();
    int lengthField = messageBuffer.getInt();
    System.out.println("lengthField="+lengthField);
    int responseLength = lengthField - 12;
    System.out.println("responseLength="+responseLength);
    String messageDecoded= messageDecoder.decode(messageBuffer).toString();
    System.out.println("messageDecoded="+messageDecoded);
    String decodedCarrier = messageDecoded.substring(0, carrierName.length());
    System.out.println("decodedCarrier="+ decodedCarrier);
    String decodedBody = messageDecoded.substring(carrierName.length(), messageDecoded.length() - 1);
    System.out.println("decodedBody="+decodedBody);

    Assertions.assertThat(messageLength).isEqualTo(lengthField);
    Assertions.assertThat(decodedBody).isEqualTo(message);
    Assertions.assertThat(decodedBody).isEqualTo(message);

    ByteBuffer messageBuffer2 = ByteBuffer.allocate(4096);
    messageBuffer2.order(ByteOrder.BIG_ENDIAN);
    messageBuffer2.putInt(messageLength);
    messageBuffer2.put(messageEncoder.encode(CharBuffer.wrap(carrierName)));
    messageBuffer2.put(messageEncoder.encode(CharBuffer.wrap(message)));
    messageBuffer2.put((byte) 0x2b);
    messageBuffer2.flip();

    System.out.println("---------Extract Data Approach 2--------");

    byte [] data = new byte[messageBuffer2.limit()];
    messageBuffer2.get(data);
    String dataString =new String(data, "ISO-8859-1");
    System.out.println(dataString);

}
}

Он работает нормально, но потом я подумал о его рефакторинге, см. Подход 2 в приведенном выше коде

    byte [] data = new byte[messageBuffer.limit()];
    messageBuffer.get(data);
    String dataString =new String(data, "ISO-8859-1");
    System.out.println(dataString);

 Output=     #CARR00ABTRANSACTION IGNORED+

Не могли бы выребята, помогите мне с объяснением

  1. почему во втором подходе при декодировании пропускается целое число ???

  2. Есть ли способ извлечьцелое число во втором подходе ??

1 Ответ

0 голосов
/ 13 декабря 2018

Хорошо, вы пытаетесь прочитать int из буфера, который занимает 4 bits, а затем пытаетесь получить все данные после чтения 4 bits

Что я сделал, так это позвонил messageBuffer2.clear(); после прочтения int, чтобы решить эту проблему.вот полный код

System.out.println(messageBuffer2.getInt());
byte[] data = new byte[messageBuffer2.limit()];
messageBuffer2.clear();
messageBuffer2.get(data);
String dataString = new String(data, StandardCharsets.ISO_8859_1);
System.out.println(dataString);

Вывод:

35
   #CARR0033TRANSACTION IGNORED+

Редактировать: Таким образом, в основном, когда вы звоните clear, он сбрасывает различные переменные и также сбрасывает позицию, из которой он получаети вот как это исправить.

...