2013-02-20 42 views
5

我正在將一堆舊的製表符分隔的MySQL數據庫轉儲文件轉換爲協議緩衝區,並且遇到了麻煩。 MySQL表包含int(11) unsigned類型的字段,我已將其映射到.proto文件中的protobuf uint32。當解析MySQL記錄並嘗試將它們轉換爲protobuf消息時,很容易使用Integer.valueOf(String)(或Long.valueOf(String)來避免溢出)解析該字段。然而,Protocol Buffers Language Guide指示here在Java中,uint32s使用int數據類型來表示,但是第一位被重新解釋爲最高位而不是符號位。如何將Java無符號整數轉換爲Java中的協議緩衝區uint32s?

因此,在我去寫我自己的Stringuint32 -flavored- int解析器,我認爲值得問問是否有人已經解決了這個問題。什麼是將MySQL int unsignedString表示形式轉換爲Java中的協議緩衝區uint32的正確方法?

回答

1

字符串爲int表示UINT32

我會嘗試解析爲long,然後轉換爲int

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

使用long的轉換避免了NumberFormatException由於超出範圍。隨後的narrowing conversion將丟棄更重要的一半結果位,使您完全符合協議緩衝區所需的表示。

字符串到長表示UINT64

類似的轉換用於使用如下(未測試的代碼)BigInteger很可能被寫入uint64

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

這依賴於一個隱含的截斷,就像在上述案件。 documentation陳述如下:

如果BigInteger太大而不適合long,只返回低位64位。

詮釋代表UINT長

如果要轉換這樣實際上代表uint32long有積極的跡象的int,你應該確保清除32最顯著位,因爲這些將由於widening conversion的符號擴展性質,填充值爲int的最高有效位的副本。

long uintValue = intValue & 0xffffffffL; 
+0

我得出了類似的結論,但是你比我更乾淨地實施它。這提出了一個類似的問題:如何通過Java解析'unsigned bigint'到protobuf'uint64'? – 2013-02-21 18:37:32

+0

您的解決方案還表明,可以簡單地通過從'int'轉換回'long'來完成未轉換,這很好。 – 2013-02-21 18:38:02

+0

@JoshHansen,我對你的評論做出了迴應。 – MvG 2013-02-21 22:08:15

0

如果字節順序不是問題,那麼你可以威脅無符號整數作爲固定長度的字節數組。