2015-05-29 13 views
5

की प्रतिलिपि के बिना बाइटस्ट्रिंग से बाइट सरणी प्राप्त करें मान लीजिए मेरे पास एक विधि है void foo(byte[] bytes) को इसके पैरामीटर के रूप में बाइट सरणी की आवश्यकता है। Howverver, Protobuf में बाइट सरणी के लिए जावा प्रकार ByteString है।प्रोटोकॉल बफर:

मैं बाइट सरणी प्राप्त करने के लिए byte[] toByteArray() का उपयोग कर सकता हूं। लेकिन समस्या यह है कि यह विधि कॉपी का उपयोग करके एक नई सरणी बनाती है, जो अपेक्षाकृत महंगी है। मैं इसके बजाय अंतर्निहित सरणी सीधे वापस कर दूंगा, या इसके बजाय एक दृश्य वापस करूँगा।

क्या इसके लिए कोई एपीआई है, या प्रदर्शन जुर्माना स्वीकार्य है?

+0

foo (बाइट [] बाइट्स) विधि क्या करता है? क्या आप इसका कार्यान्वयन बदल सकते हैं? – kostya

+0

@ कोस्ट्या क्या आपका मतलब है कि मैं 'बाइटस्ट्रिंग # लिखने के लिए (आउटपुटस्ट्रीम)' का उपयोग कर सकता हूं? लेकिन मैं वास्तव में चाहता हूं कि मेरे मॉड्यूल एक-दूसरे से डीकॉप्ल हो जाएं। – duleshi

+0

हां, 'लिखने के लिए कुछ'। 'आउटपुटस्ट्रीम' मानक लाइब्रेरी से एक कक्षा है, इसलिए आप अभी भी foo() विधि protobuf मुक्त रख सकते हैं। 'बाइटस्ट्रिंग' के लिए जावाडॉक्स स्पष्ट रूप से कहते हैं कि जो भी आप पूछते हैं वह असंभव है: 'स्ट्रिंग' की तरह, 'बाइटस्ट्रिंग' की सामग्री को बदलने के लिए कभी नहीं देखा जा सकता है, क्लाइंट कोड में डेटा रेस या गलत एपीआई उपयोग की उपस्थिति में भी नहीं । – kostya

उत्तर

4

सामान्यतः यह असंभव है क्योंकि ByteString के कुछ उप-वर्गों के अंदर ऐसी कोई सरणी नहीं हो सकती है। BoundedByteString में एक बड़ा सरणी हो सकती है, इसलिए सही आकार की सरणी प्राप्त करने के लिए प्रतिलिपि बनाना आवश्यक है। RopeByteString में अन्य बाइट स्ट्रिंग्स शामिल हैं इसलिए प्रतिलिपि बनाना इसे एक सरणी में रखना आवश्यक है। LiteralByteString इसे सामग्री को सही आकार की एक सरणी में संग्रहीत करता है, लेकिन यह इसे सीधे एक्सेस करने के तरीकों को प्रदान नहीं करता है।

लेकिन संभवतः toByteArray() आपकी आवश्यकताओं के लिए पर्याप्त तेज़ होगा System.arraycopy() बहुत तेज़ है।

तुम सच में लंबे सरणियों नकल की वजह से एक प्रदर्शन समस्या है और आप ByteString सीधे पारित करने के लिए नहीं करना चाहते हैं, asReadOnlyByteBuffer() और asReadOnlyByteBufferList() तरीकों पर एक नजर है। वे ByteString सामग्री को ByteBuffer में कॉपी किए बिना लपेटते हैं।

2

आप एक ByteString से एक byte[] नकल के बिना नहीं मिल सकता है, क्योंकि यह आप जिसका अर्थ है कि ByteString अब की गारंटी दे सकें कि यह अपरिवर्तनीय है ByteString की सामग्री को संशोधित करने की अनुमति होगी। यह String से प्रतिलिपि के बिना सेका समर्थन करता है, भले ही आपकोसेप्राप्त नहीं हो सकता है। यह एक सुरक्षा समस्या हो सकती है: जब सुरक्षा डोमेन के बीच String या ByteString गुजरते समय, यह महत्वपूर्ण है कि रिसीवर यह जान सके कि प्रेषक इसका उपयोग करते समय स्ट्रिंग को उनके नीचे से संशोधित नहीं कर रहा है।

हालांकि, आप asReadOnlyByteBufferList() फोन एक प्रति के बिना ByteBuffer अंतर्निहित डेटा का प्रतिनिधित्व रों प्राप्त करने के लिए, के बाद से ByteBuffer अचल स्थिति को लागू करता है सकते हैं।

संबंधित मुद्दे