2012-02-19 101 views
8

所以我在这里要做的是得到一个float[],将它转换为byte[],通过网络发送它作为数据报包,然后将其转换回接收终端处的byte[]将float []转换为byte []再次浮动[]

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

+0

很好地回答这里:http://stackoverflow.com/a/19624671/534347 – 2014-08-14 20:20:26

回答

9

我想你想使用ByteBuffer类,它有putFloatgetFloat方法。

+0

谢谢!我觉得这就是。当我得到时间时,我会给它一个去,我会让你知道发生了什么。 – brain56 2012-02-19 04:49:47

+1

@ brain56:只是想补充一点,如果你通过网络发送这个消息,你会希望明确指定一个编码,而不是让自己置于平台默认编码的控制之下。 – 2012-02-19 05:09:52

+1

ByteBuffer也有asFloatBuffer()方法,如果你不想单独提取值,你可以链接方法调用:ByteBuffer.wrap(someByteArray).asFloatBuffer()。array()从一个byte []到一个float [] – 2014-08-08 18:51:58

2

使用Float.floatToIntBits()来提取float的位值作为整数,然后使用BigInteger.toByteArray()来创建byte[]。这可以通过使用BigInteger构造函数来取消,该构造函数采用byte[]参数,然后使用Float.intBitsToFloat()

5

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

什么是downvote? – ricosrealm 2012-11-16 02:08:27

+0

没有像writeFloat这样的方法 - 您的代码根本无法编译 – pzo 2012-11-16 23:45:53

+1

感谢您指出,我更新了正确的适配器类的代码。 – ricosrealm 2012-11-17 20:30:51

0

发件人

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

您需要使用getFloat()和putFloat()的字节缓冲区的FloatBuffer命令。事实上,你完全应该这样做,只是因为速度很快。对于字节操作来说这是一件很棒的事情。您也可以混合和匹配数据,并根据需要放置和获取数据。所有这些都由字节缓冲区支持。所以发送数组的常见情况,你也需要发送数组的大小。

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