2013-02-20 92 views
5

मैं पुराने टैब-पृथक MySQL डेटाबेस डंप फ़ाइलों का एक समूह प्रोटोकॉल बफर में परिवर्तित करने पर काम कर रहा हूं और एक स्नैग में चला गया हूं। MySQL तालिका में int(11) unsigned प्रकार का एक फ़ील्ड शामिल है, जिसे मैंने .proto फ़ाइल में protobuf uint32 पर मैप किया है। MySQL रिकॉर्ड्स को पार्स करते समय और उन्हें प्रोटोबफ संदेश में बदलने की कोशिश करते समय, ओवरफ्लो से बचने के लिए Integer.valueOf(String) (या Long.valueOf(String)) का उपयोग करके उस क्षेत्र को पार्स करने का मोहक है। हालांकि, Protocol Buffers Language Guidehere इंगित करता है कि जावा में, uint32 एस int डेटाटाइप का उपयोग करके दर्शाए जाते हैं, लेकिन पहले बिट को साइन बिट के बजाए उच्चतम ऑर्डर बिट के रूप में पुन: परिभाषित किया जाता है।मैं जावा में प्रोटोकॉल बफर uint32s में MySQL हस्ताक्षरित इनट्स कैसे परिवर्तित करूं?

तो इससे पहले कि मैं अपने ही String बारे में जाना ->uint32 -flavored- int पार्सर, मैंने सोचा था कि किसी और को पहले से ही इस विशेष समस्या को हल किया है कि क्या यह पूछ लायक था। जावा में प्रोटोकॉल बफर uint32 पर String MySQL int unsigned का प्रतिनिधित्व करने का सही तरीका क्या है?

उत्तर

1

स्ट्रिंग का प्रतिनिधित्व uint32

मैं long के रूप में पार्स करने चाहते हैं की कोशिश और उसके बाद int में परिवर्तित करने के लिए int। बाद के narrowing conversion परिणामस्वरूप बिट्स का अधिक महत्वपूर्ण आधा छोड़ देगा, जो आपको प्रोटोकॉल बफर द्वारा आवश्यक प्रतिनिधित्व के साथ छोड़ देगा।

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

यह एक अंतर्निहित काट-छांट पर निर्भर करता है, बस ऊपर में की तरह:

लंबे uint64

ऐसा ही एक रूपांतरण का प्रतिनिधित्व uint64 का उपयोग कर BigInteger शायद के रूप में (अपरीक्षित कोड) इस प्रकार लिखा जा सकता है के लिए करने के लिए स्ट्रिंग मामला। documentation कहता है:

यदि यह BigInteger एक लंबे, केवल कम क्रम 64 बिट्स लौटा दिया जाता है में फिट करने के लिए बहुत बड़ा है।

इंट आप कन्वर्ट करने के लिए इस तरह के एक int जो वास्तव में सकारात्मक संकेत के साथ एक long के लिए एक uint32 का प्रतिनिधित्व करता है, तो आप 32 सबसे महत्वपूर्ण बिट स्पष्ट करने के लिए यह सुनिश्चित करना चाहिये चाहते हैं लंबे

को uint, प्रतिनिधित्व के रूप में इन होगा widening conversion की साइन-विस्तार प्रकृति के कारण, int मान के सबसे महत्वपूर्ण बिट की प्रतियों से भरे रहें।

long uintValue = intValue & 0xffffffffL; 
+0

मैं इसी तरह के निष्कर्ष पर आया था, लेकिन आपने इसे जितना अधिक साफ किया है उससे लागू किया है। यह एक समान प्रश्न का सुझाव देता है: जावा के माध्यम से 'uint64' protobuf' को 'हस्ताक्षरित bigint' को कैसे पार्स करें? –

+0

आपका समाधान यह भी बताता है कि 'int' से' long' तक कास्टिंग करके आसानी से अपरिवर्तित किया जा सकता है, जो अच्छा है। –

+0

@ जोशहांसेन, मैंने आपकी टिप्पणियों के जवाब में अपना जवाब अपडेट किया। – MvG

0

यदि अंतहीनता कोई समस्या नहीं है, तो आप निश्चित लंबाई के बाइट एरे के रूप में हस्ताक्षरित इनट्स को खतरे में डाल सकते हैं। एक से अधिक हो गई सीमा की वजह से

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

रूपांतरण के लिए एक NumberFormatException से बचा जाता है long का उपयोग करना: