Преобразуйте float [] в byte [], чтобы снова плавать [] - PullRequest
8 голосов
/ 19 февраля 2012

Итак, я пытаюсь получить float[], преобразовать его в byte[], отправить через сеть в виде пакета дейтаграмм и затем преобразовать обратно в byte[] на принимающем терминале.

Теперь я знаю, что могу конвертировать float[] в byte[], используя метод getBytes[].Но я не знаю, как перевернуть конверсию.

Ответы [ 7 ]

9 голосов
/ 19 февраля 2012

Я думаю, вы хотите использовать класс ByteBuffer, который имеет методы putFloat и getFloat.

5 голосов
/ 19 февраля 2012

Другой способ ... использовать ByteArrayOutputStream / DataOutputStream для вывода

float fArr[] = ...;
ByteArrayOutputStream bas = new ByteArrayOutputStream();
DataOutputStream ds = new DataOutputStream(bas);
for (float f : fArr) 
    ds.writeFloat(f);
byte[] bytes = bas.toByteArray();

Используйте ByteArrayInputStream / DataInputStream для ввода

byte[] buffer = ...;
ByteArrayInputStream bas = new ByteArrayInputStream(buffer);
DataInputStream ds = new DataInputStream(bas);
float[] fArr = new float[buffer.length / 4];  // 4 bytes per float
for (int i = 0; i < fArr.length; i++)
{
    fArr[i] = ds.readFloat();
}
2 голосов
/ 19 февраля 2012

Используйте Float.floatToIntBits(), чтобы извлечь битовое значение с плавающей точкой как целое число, затем используйте BigInteger.toByteArray(), чтобы получить byte[].Это можно изменить с помощью конструктора BigInteger, который принимает аргумент byte[], а затем Float.intBitsToFloat().

1 голос
/ 27 сентября 2018

Это больше для моей будущей ссылки, чем что-либо еще.

public static byte[] floatToByte(float[] input) {
    byte[] ret = new byte[input.length*4];
    for (int x = 0; x < input.length; x++) {
        ByteBuffer.wrap(ret, x*4, 4).putFloat(input[x]);
    }
    return ret;
}

public static float[] byteToFloat(byte[] input) {
    float[] ret = new float[input.length/4];
    for (int x = 0; x < input.length; x+=4) {
        ret[x/4] = ByteBuffer.wrap(input, x, 4).getFloat();
    }
    return ret;
}

Может быть уменьшено до одной строки, например https://stackoverflow.com/a/44104399/322017.

0 голосов
/ 22 мая 2017

Вам необходимо использовать команды getFloat () и putFloat () в FloatBuffer ByteBuffer.На самом деле, вы должны сделать это просто из-за высокой скорости.И это замечательно для манипуляций с байтами.Вы также можете смешивать и сопоставлять данные, а также помещать и получать их по мере необходимости.Все это поддерживается байтовым буфером.Таким образом, обычно происходит отправка массива, вам также необходимо отправить размер массива.

public static void writeFloatArray(float[] array, OutputStream stream) throws IOException {
    ByteBuffer buffer = ByteBuffer.allocate(4 * (array.length + 1)).putInt(array.length);
    buffer.asFloatBuffer().put(array,0,array.length);
    stream.write(buffer.array());
}

Вы просто должны выделить достаточно байтов для хранения всего в буфере.Напишите кое-что, напишите что-нибудь другое и т. Д. Понимание этого пункта облегчает жизнь.С другой стороны, мы делаем в основном то же самое, хотя нам требуется дополнительное чтение, потому что мы не знаем, насколько велик массив, просто есть один:

public static float[] readFloatArray(InputStream in) throws IOException {
    byte[] data = new byte[4];
    if (readFully(in, data) != data.length) return null;
    int length = ByteBuffer.wrap(data).getInt();
    data = new byte[length * 4];
    if (readFully(in,data) != data.length) return null;
    float[] array = new float[length];
    ByteBuffer.wrap(data).asFloatBuffer().get(array,0,array.length);
    return array;
}

И для полной функциональности, хотя и неименно часть этого:

public static int readFully(InputStream in, byte[] data) throws IOException {
    int offset = 0;
    int bytesRead;
    boolean read = false;
    while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
        read = true;
        offset += bytesRead;
        if (offset >= data.length) {
            break;
        }
    }
    return (read) ? offset : -1;
}
0 голосов
/ 19 февраля 2016

Отправитель :

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
// byteBuffer reused for every element in floatArray
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
// go through the elements in the float array writing its
// byte equivalent  to the stream
for(float element : floatArray) {
  byteBuffer.clear();
  byteBuffer.putFloat(element)
  byteStream.write(byteBuffer.array());
}

// Logic for sending bytestream's bytes as datagram packet
// can get byte[] from steam by: byteStream.toByteArray();

Получатель :

ArrayList<Float> receivedValues = new ArrayList<Float>();
ByteBuffer byteBuffer = ByteBuffer.wrap(receivedBytes);

// while there is still 4 bytes left on the byte buffer
// grab the next float and add it to the received list
int position = 0;
while(byteBuffer.capactiy - position >= 4) {
  receivedValues.add(byteBuffer.getFloat(position));
  position += 4;
}

float[] result = new float[receivedValues.count];
return receivedValues.toArray(new float[receivedValues.size()]);
0 голосов
/ 19 февраля 2012

Байт-класс имеет метод floatValue ();

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Byte.html#floatValue%28%29

...