Приведение double [] к byte [] с использованием потока в Java - PullRequest
0 голосов
/ 20 мая 2018

Эй, я работаю над приложением, которое использует Paho mqtt

Теперь я пытаюсь преобразовать содержимое пары объектов в байтовые массивы, чтобы я мог отправить их брокеру.Есть пара различных объектов, которые все привязаны к абстрактному классу, но тот, с которого я начал, содержит двойной []

Вот функция, которую я пытаюсь реализовать:

    @Override
public byte[] getBytes() {

    return Arrays.stream(driveVector).map(d -> Double.valueOf(d).byteValue()).toArray();
}

Я думал, что это будет работать, но я получаю сообщение об ошибке, что возвращаемое значение является двойным []

Я думаю, что я либо не понимаю метод карты, либо я в общем-то ошибаюсь ((Я посмотрел на класс ByteBuffer, но, кажется, это трудно реализовать с ним)

Заранее спасибо

Ответы [ 4 ]

0 голосов
/ 20 мая 2018

В моем приложении MQTT я прочитал одно двойное значение и отправил его брокеру.Тем не менее, нет никакой реальной разницы между синглом и массивом парных чисел.Клиент должен знать длину массива, в то время как с одним значением он всегда знает, что он есть.

Я уверен, что вы можете адаптировать мой код для записи нескольких значений, а toMessage - для записи несколькихdouble значения.

public abstract class SensorMonitor {
  protected final MqttAsyncClient client;
  protected final String topic;
  protected final Logger logger = Logger.getLogger(getClass().getName()); 
  private final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(8);
  private final DataOutputStream dataOut = new DataOutputStream(byteOut);

  public SensorMonitor(MqttAsyncClient mqttClient, String topic) {
    this.client = mqttClient;
    this.topic = topic;
  }

  public void start(ScheduledExecutorService service) {
    service.scheduleWithFixedDelay(this::publish, 0, 30, TimeUnit.SECONDS);
  }

  protected void publish() {
    try {
        MqttMessage message = toMessage(readNewValue());
        client.publish(topic, message);

    } catch (MqttException | IOException e) {
        logger.log(Level.SEVERE, "Could not publish message", e);
    }
  }

  private MqttMessage toMessage(double value) throws IOException {
    byteOut.reset();
    dataOut.writeDouble(value);
    return new MqttMessage(byteOut.toByteArray());
  }

  protected abstract double readNewValue();
}

DataOutputStream.writeDouble использует Double.doubleToLongBits для создания битовой разметки с двойным форматом IEEE 754.

InВ моем случае я мог бы предварительно выделить и повторно использовать выходной поток byteOut, так как заранее знал необходимый размер byte[].

0 голосов
/ 20 мая 2018

Вы не можете привести double[] к byte[] по фундаментальной причине, что они являются несвязанными типами, и вы можете выполнять приведение только между связанными типами.

Приводы в Java, в отличие, скажем, отC ++, на самом деле не создавайте новый объект: это всего лишь путь к компилятору: «Я знаю больше о типе этого объекта, чем вы; поверьте мне».Например, вы можете знать, что переменная типа Object на самом деле содержит ссылку на String, что не может знать компилятор;в этом случае вы можете привести ссылку.

Однако вы можете создать новый массив:

byte[] output = new byte[input.length];
for (int j = 0; j < input.length; j++) {
  output[j] = (byte) input[j];
}

Нет способа сделать это с потоками.Или, скорее, в том, что вы можете разбить этот код на потоковую операцию, скажем, на Stream<double[]>;но использование таких потоков явно не приносит никакой пользы.

0 голосов
/ 20 мая 2018

Вы можете использовать для этого ByteBuffer:

double[] doubles = new double[] {1,2,3,4,5};
ByteBuffer buffer = ByteBuffer.allocate(doubles.length * Double.BYTES);
Arrays.stream(doubles).forEach(buffer::putDouble);
buffer.array();
0 голосов
/ 20 мая 2018

Java Streams не является подходящим инструментом, особенно если учесть, что в Java нет ByteStream.

Ваш метод может быть реализован в виде простого цикла for.

@Override
public byte[] getBytes() {
    byte[] arr = new byte[driveVector.length];
    for (int i = 0; i < arr.length; i++)
        arr[i] = (byte) driveVector[i];
    return arr;
}
...