6

我正在将一堆旧的制表符分隔的 MySQL 数据库转储文件转换为协议缓冲区并遇到了障碍。MySQL 表包含一个类型为 的字段int(11) unsigned,我已将其映射到文件uint32中的protobuf .proto。在解析 MySQL 记录并尝试将它们转换为 protobuf 消息时,很容易使用Integer.valueOf(String)(或Long.valueOf(String)避免溢出)解析该字段。但是,Protocol Buffers Language Guide在这里指出,在 Java 中,uint32s 使用int数据类型表示,但第一位被重新解释为最高位而不是符号位。

因此,在我编写自己的String-> uint32-flavored-int解析器之前,我认为值得询问其他人是否已经解决了这个特定问题。String将MySQL 的表示形式转换为Javaint unsigned中的协议缓冲区的正确方法是什么?uint32

4

2 回答 2

2

字符串到 int 表示 uint32

我会尝试解析为long然后转换为int

int i = (int)Long.parseLong(str);

用于long转换避免了NumberFormatException由于超出范围。随后的窄化转换将丢弃结果位中较高的一半,从而为您提供协议缓冲区所需的表示形式。

字符串转长表示 uint64

类似的uint64使用转换BigInteger可能会写成如下(未经测试的代码):

long l = (new BigInteger(str)).longValue();

这依赖于隐式截断,就像上面的情况一样。该文档指出:

如果这BigInteger太大而无法放入 long 中,则仅返回低 64 位。

Int 表示 uint 到 long

如果您想将int实际代表 an 的此类转换uint32long带正号的 a,则应确保清除 32 个最高有效位,因为这些将被int值的最高有效位的副本填充,因为符号-拓宽转换性质。

long uintValue = intValue & 0xffffffffL;
于 2013-02-21T08:29:13.187 回答
0

如果字节序不是问题,那么您可以将无符号整数威胁为固定长度的字节数组。

于 2013-02-20T23:08:01.817 回答