Метод Java readInt возвращает LittleEndian, а не BigEndian значение Int в Scala

Я использую Kryo для десериализации класса, изначально сериализованного в Spark. Kryo записывает все свои примитивы в формате BigEndian, но когда я пытаюсь десериализовать значения на другом компьютере, значение возвращается, как если бы оно было LittleEndian.

Основной метод в Kryo:

public int readInt () throws KryoException {
    require(4); // Does a basic positionality check that passes in this case
    byte[] buffer = this.buffer;
    int p = this.position;
    this.position = p + 4;
    return buffer[p] & 0xFF //
        | (buffer[p + 1] & 0xFF) << 8 //
        | (buffer[p + 2] & 0xFF) << 16 //
        | (buffer[p + 3] & 0xFF) << 24;
}

Это возвращает значение 0x70000000. Но когда моя программа (на Scala) использует метод Kryo readByte:

public byte readByte () throws KryoException {
    if (position == limit) require(1);
    return buffer[position++];
}

и считывает байты по отдельности, например:

  val a = input.readByte()
  val b = input.readByte()
  val c = input.readByte()
  val d = input.readByte()
  val x = (a & 0xFF) << 24 | (b & 0xFF) << 16 | (c & 0xFF) << 8 | d & 0xFF

Затем я получаю 0x70 для x. Я не понимаю, что здесь происходит. Это какая-то проблема преобразования между Scala и Java или что-то связанное с Kryo и подчиненным массивом байтов?


person kellanburket    schedule 15.02.2019    source источник


Ответы (1)


Код, который вы написали:

  val a = input.readByte()
  val b = input.readByte()
  val c = input.readByte()
  val d = input.readByte()
  val x = (a & 0xFF) << 24 | (b & 0xFF) << 16 | (c & 0xFF) << 8 | d & 0xFF

неправильно конвертирует байты в int. Если вы внимательно изучите метод readInt(), вы увидите, что вы изменили порядок.

  val x = (a & 0xFF) | (b & 0xFF) << 8 | (c & 0xFF) << 16 | d & 0xFF << 24;

будет правильным способом написать это.

person jontro    schedule 20.02.2019