当前位置: 首页> 游戏> 游戏 > 莱芜搜狗推广_游戏网站怎么做_网站建设开发价格_关键词林俊杰mp3免费下载

莱芜搜狗推广_游戏网站怎么做_网站建设开发价格_关键词林俊杰mp3免费下载

时间:2025/7/10 13:43:18来源:https://blog.csdn.net/cuxqblt/article/details/144845370 浏览次数:0次
莱芜搜狗推广_游戏网站怎么做_网站建设开发价格_关键词林俊杰mp3免费下载

C/C++的相互转换

作为一名C/C++语言开发者,熟悉各种数据类型的底层表示,很容易就会把它们的内存地址直接进行字节型的读写。

比如我们定义了一个int的类型,在不考虑大小端的情况下,就可以直接通过按照变量地址进行读写:

// 写入一个int值到unsigned char *
void writeInt(int iv, unsigned char *p, size_t psize) 
assert (sizeof (iv) <= psize);
memcpy (p, &iv, sizeof (iv));
}// 读取一个unsigned char *到int
void readInt(int *iv, const unsigned char *p, size_t psize)
{
assert (psize >= sizeof (*iv));
*iv = * (int *) p;
}

通过DataInputStream与DataOutputStream

在Java中,这一点却没有那么简单直接。

因为Java一切皆对象,这些对象有的是值类型,有的是指针类型,但是无论是什么类型,都不支持直接对底层内存地址的数据进行读写。

虽然,比较新的Java有unsafe实现,但是unsafe也只能对对象的属性,进行偏移量级别的读写,仍然没法对底层的数据进行操作。

好在作为一个非常成熟的语言,Java在这方面包装了各种类来实现。其中,DataInputStream/DataOutputStream就是一个读写数据类型的好方法(虽然性能不佳)。

DataInputStream是DataInput接口的一个实现。为了篇幅简短,以下是DataInput去掉注释以后的源代码:

public interface DataInput {void readFully(byte[] b) throws IOException;void readFully(byte[] b, int off, int len) throws IOException;int skipBytes(int n) throws IOException;boolean readBoolean() throws IOException;byte readByte() throws IOException;int readUnsignedByte() throws IOException;short readShort() throws IOException;int readUnsignedShort() throws IOException;char readChar() throws IOException;int readInt() throws IOException;long readLong() throws IOException;float readFloat() throws IOException;double readDouble() throws IOException;String readLine() throws IOException;String readUTF() throws IOException;}

DataInputStream类是一个包装类,可以包装在底层的InputStream上。如果包装一个ByteArrayInputStream,就可以实现对byte[]的读取了。

同理,使用DataOutputStream包装在ByteArrayOutputStream上,就可以实现对byte[]的写入。

因为DataOutputStream实现了DataOutput接口。与DataInput类似,DataOutput接口如下:

public interface DataOutput {void write(int b) throws IOException;void write(byte[] b) throws IOException;void write(byte[] b, int off, int len) throws IOException;void writeBoolean(boolean v) throws IOException;void writeByte(int v) throws IOException;void writeShort(int v) throws IOException;void writeChar(int v) throws IOException;void writeInt(int v) throws IOException;void writeLong(long v) throws IOException;void writeFloat(float v) throws IOException;void writeDouble(double v) throws IOException;void writeBytes(String s) throws IOException;void writeChars(String s) throws IOException;void writeUTF(String s) throws IOException;}

以下两个函数片段演示了具体的数据类型与字节数组的交互:

    public byte[] ToByteArray() throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);dataOutputStream.writeBoolean(true);dataOutputStream.writeByte(1);dataOutputStream.writeShort(1);dataOutputStream.writeInt(1);dataOutputStream.writeLong(1);dataOutputStream.writeFloat(1.0f);dataOutputStream.writeDouble(1.0d);dataOutputStream.writeUTF("hello,world");byteArrayOutputStream.close();return byteArrayOutputStream.toByteArray();}public void fromByteArray(byte[] bytes) throws IOException {ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);boolean bo = dataInputStream.readBoolean();byte b = dataInputStream.readByte();short s = dataInputStream.readShort();int i = dataInputStream.readInt();long l = dataInputStream.readLong();float f = dataInputStream.readFloat();double d = dataInputStream.readDouble();String str = dataInputStream.readUTF();dataInputStream.close();}

通过ByteBuffer

伴随NIO一起被引入Java语言的,还有ByteBuffer。

ByteBuffer是方便做io的缓冲区读写的,我们可以使用它的读写基本类型的接口,来完成byte[]的操作。

比如,我们如果要把基本类型转成byte[],可以先按照每种类型的大小,创建一个ByteBuffer,然后设置值之后,返回它的arrry,即byte[]。

以下是short、int、long、float、double转成byte[]的转换函数:

    public static byte[] shortToBytes(short s) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocate(Short.BYTES);byteBuffer.putShort(s);return byteBuffer.array();}public static byte[] intToBytes(int i) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocate(Integer.BYTES);byteBuffer.putInt(i);return byteBuffer.array();}public static byte[] longToBytes(long l) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES);byteBuffer.putLong(l);return byteBuffer.array();}public static byte[] floatToBytes(float f) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocate(Float.BYTES);byteBuffer.putFloat(f);return byteBuffer.array();}public static byte[] doubleToBytes(double d) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocate(Double.BYTES);byteBuffer.putDouble(d);return byteBuffer.array();}

如果要反过来转化,则可以先把确定大小的byte[]数组,转成ByteBuffer,之后再调用ByteBuffer的读取方法。

如:

    public static short shortFromBytes(byte[] bytes) throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);return byteBuffer.getShort();}public static int intFromBytes(byte[] bytes) throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);return byteBuffer.getInt();}public static long longFromBytes(byte[] bytes) throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);return byteBuffer.getLong();}public static float floatFromBytes(byte[] bytes) throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);return byteBuffer.getFloat();}public static double doubleFromBytes(byte[] bytes) throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);return byteBuffer.getDouble();}

直接转化

上面两种转换方法,都引入了中间对象,有了对象创建与释放的开销,如果追求高性能,还是直接转化比较简单直接。

因为short、int、long类型,不像浮点数那样,有具体语言实现的存储方式,所以可以直接按照字节做运算转化。而float、double都有转换成int、long的实现,可以先转换成int、long再转化成byte[]。

比如:

public static byte[] directShortToBytes(short s) throws IOException {  byte[] bytes = new byte[Short.BYTES];  bytes[0] = (byte) (s >> 8 & 0xFF);  bytes[1] = (byte) (s & 0xFF);  return bytes;  
}  public static byte[] directIntToBytes(int i) throws IOException {  byte[] bytes = new byte[Integer.BYTES];  bytes[0] = (byte) (i >> 24 & 0xFF);  bytes[1] = (byte) (i >> 16 & 0xFF);  bytes[2] = (byte) (i >> 8 & 0xFF);  bytes[3] = (byte) (i & 0xFF);  return bytes;  
}  public static byte[] directLongToBytes(long l) throws IOException {  byte[] bytes = new byte[Long.BYTES];  bytes[0] = (byte) (l >> 56 & 0xFF);  bytes[1] = (byte) (l >> 48 & 0xFF);  bytes[2] = (byte) (l >> 40 & 0xFF);  bytes[3] = (byte) (l >> 32 & 0xFF);  bytes[4] = (byte) (l >> 24 & 0xFF);  bytes[5] = (byte) (l >> 16 & 0xFF);  bytes[6] = (byte) (l >> 8 & 0xFF);  bytes[7] = (byte) (l & 0xFF);  return bytes;  
}  public static byte[] directFloatToBytes(float f) throws IOException {  int i = Float.floatToIntBits(f);  return directIntToBytes(i);  
}  public static byte[] directDoubleToBytes(double d) throws IOException {  long l = Double.doubleToLongBits(d);  return directLongToBytes(l);  
}  

以下是相反的实现:

public static short directShortFromBytes(byte[] bytes) throws IOException {  short s = (short) (bytes[0] << 8);  s += bytes[1];  return s;  
}  public static int directIntFromBytes(byte[] bytes) throws IOException {  int i = bytes[0] << 24;  i += bytes[1] << 16;  i += bytes[2] << 8;  i += bytes[3];  return i;  
}  public static long directLongFromBytes(byte[] bytes) throws IOException {  long l = ((long) bytes[0]) << 56;  l += ((long) bytes[1]) << 48;  l += ((long) bytes[2]) << 40;  l += ((long) bytes[3]) << 32;  l += bytes[4] << 24;  l += bytes[5] << 16;  l += bytes[6] << 8;  l += bytes[7];  return l;  
}  public static float directFloatFromBytes(byte[] bytes) throws IOException {  int i = directIntFromBytes(bytes);  return Float.intBitsToFloat(i);  
}  public static double directDoubleFromBytes(byte[] bytes) throws IOException {  long l = directLongFromBytes(bytes);  return Double.longBitsToDouble(l);  
}
关键字:莱芜搜狗推广_游戏网站怎么做_网站建设开发价格_关键词林俊杰mp3免费下载

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: