将 float[] 转换为 byte[] 再次转换为 float[]

发布于 2025-01-07 04:04:57 字数 200 浏览 2 评论 0原文

所以我在这里想做的是获取一个 float[] ,将其转换为 byte[] ,将其作为数据报包通过网络发送,然后将其转换返回到接收终端的byte[]

现在我知道我可以使用 getBytes[] 方法将 float[] 转换为 byte[] 。但我不知道如何反转转换。

So what I'm trying to do here is get a float[], convert it to byte[], send it through the network as a datagram packet and then convert it back to a byte[] at the receiving terminal.

Now I know I can convert float[] to byte[] by using the getBytes[] method. But I don't know how to reverse the conversion.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

月竹挽风 2025-01-14 04:04:57

我认为您想使用 ByteBuffer 类,它具有 putFloat 和 getFloat 方法。

I think you want to make use of the ByteBuffer class, which has putFloat and getFloat methods.

夏天碎花小短裙 2025-01-14 04:04:57

另一种方式...使用 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();
}

Another way... use ByteArrayOutputStream/DataOutputStream for output

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

Use ByteArrayInputStream/DataInputStream for input

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();
}
单身狗的梦 2025-01-14 04:04:57

Steven Chou 答案的改进

final static int BYTES_IN_FLOAT = Float.SIZE / Byte.SIZE;

public static byte[] toByteArray(float[] floatArray) {
    ByteBuffer buffer = ByteBuffer.allocate(floatArray.length * BYTES_IN_FLOAT)
    buffer.asFloatBuffer().put(floatArray);
    return buffer.array();
}


public static float[] toFloatArray(byte[] byteArray) {
    float[] result = new float[byteArray.length / BYTES_IN_FLOAT];
    ByteBuffer.wrap(byteArray).asFloatBuffer().get(result, 0, result.length);
    return result;
}

An improvement to Steven Chou's answer

final static int BYTES_IN_FLOAT = Float.SIZE / Byte.SIZE;

public static byte[] toByteArray(float[] floatArray) {
    ByteBuffer buffer = ByteBuffer.allocate(floatArray.length * BYTES_IN_FLOAT)
    buffer.asFloatBuffer().put(floatArray);
    return buffer.array();
}


public static float[] toFloatArray(byte[] byteArray) {
    float[] result = new float[byteArray.length / BYTES_IN_FLOAT];
    ByteBuffer.wrap(byteArray).asFloatBuffer().get(result, 0, result.length);
    return result;
}
微凉 2025-01-14 04:04:57

使用 Float.floatToIntBits() 将浮点的位值提取为整数,然后使用 BigInteger.toByteArray() 生成 byte[]< /代码>。可以使用采用 byte[] 参数的 BigInteger 构造函数,然后使用 Float.intBitsToFloat() 来逆转这一情况。

Use Float.floatToIntBits() to extract the bit-value of the float as an integer, then use BigInteger.toByteArray() to make a byte[]. This can be reversed using the BigInteger constructor that takes a byte[] argument, and then Float.intBitsToFloat().

送舟行 2025-01-14 04:04:57

这对我以后的参考比什么都重要。

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

This is more for my future reference than anything else.

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;
}

Can be reduced to a single line like https://stackoverflow.com/a/44104399/322017.

海未深 2025-01-14 04:04:57

发件人

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()]);

Sender:

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();

Receiver:

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()]);
迷迭香的记忆 2025-01-14 04:04:57

需要在ByteBuffer的FloatBuffer中使用getFloat()和putFloat()命令。事实上,您当然应该这样做,因为速度太快了。理解字节操作是一件很棒的事情。您还可以混合和匹配数据,并根据需要放置和获取数据。所有这些都由字节缓冲区支持。因此,发送数组的常见情况是,您还需要发送数组的大小。

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;
}

You need to use the getFloat() and putFloat() commands in the FloatBuffer of the ByteBuffer. In fact, you should certainly do this simply because of the sheer speed. And it's a great thing to understand for byte manipulations. You can also mix and match the data, and put and get it as needed. All of it is backed by the byte buffer. So the common happening of sending an array, you need to send the size of the array too.

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());
}

You just make sure to allocate enough bytes to store everything in the buffer. Write some stuff, write some other stuff etc. Understanding this point makes things way easier. On the flipside we do basically the same thing, though we require an additional read because we don't know how big the array is, just that there is one:

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;
}

And for full functionality, though not exactly part of this:

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;
}
十秒萌定你 2025-01-14 04:04:57

ByteBuffer 文档: https://docs.oracle.com /javase/7/docs/api/java/nio/ByteBuffer.html

final static int nbBytesInFloat = Float.SIZE / Byte.SIZE;

public static byte[] toByteArray(float[] floatArray){
    byte[] result = new byte[floatArray.length * nbBytesInFloat];
    ByteBuffer wrappedBytes = ByteBuffer.wrap(result);
    for(int i=0;i<floatArray.length;i++) {
        wrappedBytes.putFloat(floatArray[i]);
    }
    return result;
}


public static float[] toFloatArray(byte[] byteArray){
    ByteBuffer buffer = ByteBuffer.wrap(byteArray);

    float[] result = new float[byteArray.length / nbBytesInFloat];
    for(int i=0;i<result.length;i++) {
        result[i] = buffer.getFloat();
    }
    return result;
}

如果您的应用程序对性能更加敏感,那么您可以考虑这种解决方案,而无需创建许多对象:

public byte[] floatArrayToByteArray(float[] floatArray) {
    byte[] byteArray = new byte[floatArray.length * 4];
    int byteArrayIndex = 0;
    for (int i = 0; i < floatArray.length; i++) {
        int rawInt = Float.floatToRawIntBits(floatArray[i]);
        byteArray[byteArrayIndex] = (byte) (rawInt >>> 24);
        byteArray[byteArrayIndex + 1] = (byte) (rawInt >>> 16);
        byteArray[byteArrayIndex + 2] = (byte) (rawInt >>> 8);
        byteArray[byteArrayIndex + 3] = (byte) (rawInt);
        byteArrayIndex += 4;
    }
    return byteArray;
}

ByteBuffer document: https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

final static int nbBytesInFloat = Float.SIZE / Byte.SIZE;

public static byte[] toByteArray(float[] floatArray){
    byte[] result = new byte[floatArray.length * nbBytesInFloat];
    ByteBuffer wrappedBytes = ByteBuffer.wrap(result);
    for(int i=0;i<floatArray.length;i++) {
        wrappedBytes.putFloat(floatArray[i]);
    }
    return result;
}


public static float[] toFloatArray(byte[] byteArray){
    ByteBuffer buffer = ByteBuffer.wrap(byteArray);

    float[] result = new float[byteArray.length / nbBytesInFloat];
    for(int i=0;i<result.length;i++) {
        result[i] = buffer.getFloat();
    }
    return result;
}

If your application is more performance sensitive, then you can consider this solution without creating many objects:

public byte[] floatArrayToByteArray(float[] floatArray) {
    byte[] byteArray = new byte[floatArray.length * 4];
    int byteArrayIndex = 0;
    for (int i = 0; i < floatArray.length; i++) {
        int rawInt = Float.floatToRawIntBits(floatArray[i]);
        byteArray[byteArrayIndex] = (byte) (rawInt >>> 24);
        byteArray[byteArrayIndex + 1] = (byte) (rawInt >>> 16);
        byteArray[byteArrayIndex + 2] = (byte) (rawInt >>> 8);
        byteArray[byteArrayIndex + 3] = (byte) (rawInt);
        byteArrayIndex += 4;
    }
    return byteArray;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文