Convert float[] to byte[] to float[] again

前端 未结 8 1593
伪装坚强ぢ
伪装坚强ぢ 2020-12-31 15:17

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

相关标签:
8条回答
  • 2020-12-31 15:53

    Byte class has a method floatValue();

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

    0 讨论(0)
  • 2020-12-31 15:55

    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;
    }
    
    0 讨论(0)
  • 2020-12-31 15:57

    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;
    }
    
    0 讨论(0)
  • 2020-12-31 16:00

    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();
    }
    
    0 讨论(0)
  • 2020-12-31 16:03

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

    0 讨论(0)
  • 2020-12-31 16:04

    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()]);
    
    0 讨论(0)
提交回复
热议问题