如何在Java中将MySQL无符号整数转换为协议缓冲区UINT32?
我正在将一堆旧的、以标签分隔的MySQL数据库转储文件转换为协议缓冲区,结果遇到了一个障碍。MySQL表包含一个类型为如何在Java中将MySQL无符号整数转换为协议缓冲区UINT32?,java,mysql,protocol-buffers,primitive,Java,Mysql,Protocol Buffers,Primitive,我正在将一堆旧的、以标签分隔的MySQL数据库转储文件转换为协议缓冲区,结果遇到了一个障碍。MySQL表包含一个类型为int(11)unsigned的字段,我已将其映射到.proto文件中的protobufuint32。当解析MySQL记录并尝试将其转换为protobuf消息时,很容易使用Integer.valueOf(String)(或Long.valueOf(String)解析该字段以避免溢出)。但是,指示在Java中,uint32s使用int数据类型表示,但第一位被重新解释为最高阶位,而不
int(11)unsigned
的字段,我已将其映射到.proto
文件中的protobufuint32
。当解析MySQL记录并尝试将其转换为protobuf消息时,很容易使用Integer.valueOf(String)
(或Long.valueOf(String)
解析该字段以避免溢出)。但是,指示在Java中,uint32
s使用int
数据类型表示,但第一位被重新解释为最高阶位,而不是符号位
因此,在我编写自己的
String
->uint32
-风格的int
解析器之前,我认为有必要询问是否有其他人已经解决了这个特定问题。将MySQLint unsigned
的String
表示转换为Java中的协议缓冲区uint32
的正确方法是什么?如果endianness不是问题,那么可以将unsigned int作为固定长度的字节数组。String-to-int表示uint32
我会尝试解析为long
,然后转换为int
:
int i = (int)Long.parseLong(str);
使用long
进行转换可避免由于超出范围而出现NumberFormatException
。后续操作将删除结果位中更重要的一半,只留下协议缓冲区所需的表示
表示uint64的长字符串
使用biginger
对uint64
进行的类似转换可能会编写如下(未测试代码):
这依赖于隐式截断,就像上面的例子一样。各国:
如果此biginger
太大,无法放入长整数,则只返回低位64位
Int表示从Int到long
如果要将实际表示uint32
的int
转换为带正号的long
,则应确保清除32个最高有效位,因为这些位将填充int
值的最高有效位的副本,这是由于
我也得出了类似的结论,但你比我执行得更干净。这就提出了一个类似的问题:如何通过Java将
unsigned bigint
解析为protobufuint64
?您的解决方案还建议,可以简单地将int
转换为long
,这很好。@JoshHansen,我更新了我的答案,以回应您的两条评论。
long l = (new BigInteger(str)).longValue();
long uintValue = intValue & 0xffffffffL;