Java 通过网络写入4字节的无符号整数
我在用java编写无符号4字节整数时遇到问题 在64位MacOS和32位Linux(Ubuntu)上,用java编写长值会产生不同的结果 或 向网络写入4字节无符号int有问题 下面的调用在我的本地OSX上非常有效Java 通过网络写入4字节的无符号整数,java,networking,casting,long-integer,unsigned,Java,Networking,Casting,Long Integer,Unsigned,我在用java编写无符号4字节整数时遇到问题 在64位MacOS和32位Linux(Ubuntu)上,用java编写长值会产生不同的结果 或 向网络写入4字节无符号int有问题 下面的调用在我的本地OSX上非常有效 writeUInt32(999999,outputstream) 把它读回给我999999 然而,当应用程序部署到网络时,写入一个长值会导致其他一些随机数(我假设endian已被切换?),读取它会给我其他一些大数 ----------完整的方法堆栈如下所示-------------
writeUInt32(999999,outputstream)
把它读回给我999999
然而,当应用程序部署到网络时,写入一个长值会导致其他一些随机数(我假设endian已被切换?),读取它会给我其他一些大数
----------完整的方法堆栈如下所示---------------
编辑:添加到一个文件,然后通过网络传输给我发送正确的值混淆!因此,当outputstream指向本地文件时,它会写入正确的值,但当outputstream指向ByteArrayOutputStream时,则写入的长值是错误的。只需使用DataOutput/InputStream即可 要编写,请将
long
强制转换为int
public void writeUInt32(
long uint32,
DataOutputStream stream
) throws IOException
{
stream.writeInt( (int) uint32 );
}
读取时,使用readInt,分配给long并屏蔽前32位以获得无符号值
public long readUInt32(
DataInputStream stream
) throws IOException
{
long retVal = stream.readInt( );
return retVal & 0x00000000FFFFFFFFL;
}
编辑
从您的问题来看,您似乎对基本类型的Java强制转换和升级感到困惑
阅读Java规范关于转换和升级的这一部分:为什么不直接使用stream.writeInt((int)uint32);因为int不能保持足够长的时间,所以它会失去价值。我必须在long而不是int中存储4个字节的数据,因为在java中int是有符号的,并且总是给“符号”分配一个位,因此java中的int比cno中的unsigned int具有更少的值,java int不具有更少的信息。这是相同的位,只是你如何解释它们。你是在读Java程序还是C程序?DataOutputStream总是写big-endian,但是从C程序中读取
int
将受到平台endian的影响。不会强制转换(int)uint32将覆盖所有大于Integer.MAX\u值的值,即使long可以保存大于Integer.MAX\u值的值?我选择long保存int值的原因是因为int是无符号的,在java中保存无符号int的唯一方法是将其声明为long。Integer.MAX_VALUE以上的一些值在C中是整数,因为java中整数的最大长度较小,因为符号被分配了1位value@Ganesh. 将long
强制转换为int
只要保证uint32只保存4个字节的数据就可以了(没有双关语)。在这个过程中,int
值可能会有符号(如果原始的long
大于0x7fffffl),但这在readUInt32中得到了处理,方法是将其转换回long
并屏蔽更高的32位。@Ganesh。我添加了一个java规范的链接,该规范解释了cast升级。@BoroC
有一个unsigned int
的概念,java
没有。重要的是,如果将表示unsigned int
概念的4个字节的数据放在一起,那么C
将正确地解释它。
public long readUInt32(
DataInputStream stream
) throws IOException
{
long retVal = stream.readInt( );
return retVal & 0x00000000FFFFFFFFL;
}