2009-09-10 13 views
28

मैं एक OutputStream लिख रहा हूँ, बस OutputStream इंटरफ़ेस में यह देखा,क्यों जावा OutputStream.write() पूर्णांक लेता है लेकिन लिखता बाइट्स

public abstract void write(int b) throws IOException; 

इस कॉल लिखने एक बाइट धारा के लिए, लेकिन क्यों यह रूप में पूर्णांक लेता है एक विवाद?

उत्तर

9

वास्तव में मैं हाल ही में बाइट्स के साथ काम कर रहा हूं और वे परेशान हो सकते हैं। वे थोड़ी सी उत्तेजना पर इनट्स में अप-कन्वर्ट करते हैं और एक संख्या को बाइट में बदलने के लिए कोई पदनाम नहीं है - उदाहरण के लिए, 8 एल आपको एक लंबा मूल्य 8 देगा, लेकिन बाइट के लिए आपको कहना होगा (बाइट) 8

उस पर, वे (बहुत ज्यादा) हमेशा आंतरिक रूप से इनट्स के रूप में संग्रहीत किए जाएंगे जबतक कि आप एक सरणी का उपयोग नहीं कर रहे हैं (और शायद तब भी .. सुनिश्चित नहीं)।

मुझे लगता है कि वे बहुत अधिक मानते हैं कि बाइट का उपयोग करने का एकमात्र कारण i/o है जहां आपको वास्तव में 8 बिट्स की आवश्यकता होती है, लेकिन आंतरिक रूप से वे आपको हमेशा इनट्स का उपयोग करने की उम्मीद करते हैं।

वैसे, एक बाइट बदतर क्योंकि यह हमेशा नकाबपोश हो गया है प्रदर्शन कर सकते हैं ...

कम से कम मैं पढ़ रहा है कि साल पहले, अब तक बदल गया होगा याद है।

अपने विशिष्ट प्रश्न के लिए एक उदाहरण जवाब के रूप में, यदि एक समारोह (च) एक बाइट ले लिया, और आप दो बाइट्स था (B1 और B2), तो:

f(b1 & b2) 

काम नहीं है, क्योंकि बी 1 & बी 2 एक int में परिवर्तित हो जाएगा, और int स्वचालित रूप से नीचे परिवर्तित नहीं किया जा सकता है (परिशुद्धता का नुकसान)। तो आपको कोड करना होगा:

f((byte)(b1 & b2)) 

जो परेशान हो जाएगा।

और पूछना परेशान न करें कि क्यों बी 1 & बी 2 अप-कनवर्ट्स - मैं हाल ही में उस पर थोड़ा सा चिल्ला रहा हूं!

+4

एमेन - जावा में बाइट मैनिपुलेशन ऐसे पॉथोल से भरा है (आमतौर पर वह प्रकार जो डिजाइन समय पर पकड़ना लगभग असंभव है)। और क्यों दुनिया में संकलक यह नहीं समझ सकता कि नया बाइट [] {0x01, 0x02} बाइट्स की एक सरणी है?मुझे नया बाइट [] {(बाइट) 0x01, (बाइट) 0x02} क्यों लिखना है?

+1

आपको केवल 0x7F से बड़े मानों को डालना होगा, क्योंकि बाइट्स पर हस्ताक्षर किए गए हैं। इसके बारे में परेशान कुछ भी नहीं है। यह हस्ताक्षरित/हस्ताक्षरित चार का गुच्छा होने से कहीं ज्यादा बेहतर है। आईडीई का प्रयोग करें, यह टाइप सुरक्षा की जांच करेगा और आपके लिए कलाकार डालेगा। मास्क ऑपरेशन एक निर्देश है, यह प्रदर्शन को प्रभावित नहीं करता है। –

6

OutputStream के लिए जावाडोक के अनुसार, इस समारोह द्वारा 24 उच्च-आदेश बिट्स को अनदेखा किया जाता है। मुझे लगता है कि विधि संगतता कारणों के लिए मौजूद है: इसलिए आपको पहले बाइट में कनवर्ट करने की आवश्यकता नहीं है और आप बस एक पूर्णांक पास कर सकते हैं।

संबंध

+2

क्या संगतता है, हालांकि? – skaffman

+1

अच्छी तरह से, संगतता इसके लिए गलत शब्द हो सकती है ... चलिए इसे सादगी या प्रोग्रामर-अनुकूल कहते हैं; ओ) – Atmocreations

+0

'लिखने (int)' और 'लिखने (बाइट []) 'के बीच की असंतोष काफी हड़ताली है, हालांकि , विशेष रूप से जब आप देखते हैं कि 'लिखना (बाइट []) का डिफ़ॉल्ट कार्यान्वयन' लूप में 'लिखना (int)' कहता है। – skaffman

24

तो तुम EOF संकेत कर सकते हैं:।

"सूचना है कि पढ़ा() एक पूर्णांक मान देता है इनपुट बाइट्स की एक धारा है, तो क्यों नहीं पढ़ता() एक बाइट मान एक वापसी प्रकार के रूप में एक int का उपयोग पढ़ने() का उपयोग करने के लिए -1 को इंगित करने के लिए अनुमति देता है कि यह धारा के अंत तक पहुंच गया है। "

http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html

+0

एमएम, अच्छा बिंदु – Atmocreations

+7

तो यदि आप लिखते हैं (-1), क्या होता है? क्या यह स्ट्रीम बंद करता है? :-) – Ken

+0

नहीं। आप आउटपुट स्ट्रीम में अजीब यूनिकोड वर्ण लिखना समाप्त कर देते हैं। लेकिन अगर आपके लेखन के लिए एक प्राप्त धारा थी (-1) मुझे विश्वास है कि यह उस धारा में धारा के अंत का संकेत देगा। स्ट्रीमिंग के लिए 3 संभावनाएं हैं: पहला 2 बाइट्स निर्दिष्ट निर्दिष्ट संख्या को स्थानांतरित करें: लिखें (बाइट [] बी, int off, int len), और लिखें (बाइट बी)। तीसरा विकल्प आपको int का उपयोग करके बाइट्स की एक अनिश्चित संख्या स्थानांतरित करने देता है। यही कारण है कि int का उपयोग किया जाता है। – sfish

2

जावा iostream कक्षाएं 1.0 के बाद से जावा का एक हिस्सा रहा है। ये कक्षाएं केवल 8 बिट डेटा से निपटती हैं। मेरा अनुमान है कि इंटरफ़ेस इस तरह डिज़ाइन किया गया था ताकि int, short, बाइट और चार मानों के लिए एक लिखने (int b) विधि को बुलाया जा सके। ये सब एक int को पदोन्नत कर रहे हैं। वास्तव में 32 बिट मशीनों पर चलने वाले अधिकांश जेवीएम, int primitive से निपटने का सबसे प्रभावी प्रकार है। कंपाइलर 32 बिट्स का उपयोग करके बाइट्स जैसे प्रकारों को स्टोर करने के लिए स्वतंत्र है। दिलचस्प बात यह है कि बाइट [] वास्तव में 8 बिट बाइट्स के अनुक्रम के रूप में संग्रहीत किया जाता है। यह समझ में आता है क्योंकि एक सरणी काफी बड़ी हो सकती है। हालांकि इंट या बाइट जैसे एकल आदिम मूल्यों के मामले में, रनटाइम पर कब्जा कर लिया गया अंतिम स्थान वास्तव में तब तक महत्वपूर्ण नहीं है जब तक व्यवहार spec के अनुरूप नहीं है।

अधिक पृष्ठभूमि:

http://www.java-samples.com/showtutorial.php?tutorialid=260

iostream कक्षाओं के लिए इस धारणा है कि फोन करने वाले केवल वास्तव में डेटा के बारे में सबसे कम 8 बिट यहाँ तक कि जब किसी पूर्णांक में गुजर परवाह करता है। यह तब तक ठीक है जब तक कॉलर जानता है कि यह वास्तव में बाइट्स से निपट रहा है, लेकिन यह एक समस्या बन जाती है जब अंतर्निहित डेटा वास्तव में पाठ होता है जो मल्टी-बाइट यूनिकोड जैसे कुछ अन्य वर्ण एन्कोडिंग का उपयोग करता है। यही कारण है कि रीडर कक्षाओं को जावा 1.1 के साथ वापस पेश किया गया था। यदि आप टेक्स्ट डेटा और प्रदर्शन की परवाह करते हैं, तो आईओएसट्रीम कक्षाएं तेज़ी से होती हैं, लेकिन रीडर कक्षाएं अधिक पोर्टेबल होती हैं।

2

शायद ऐसा इसलिए है क्योंकि बाइट डिफ़ॉल्ट रूप से हस्ताक्षरित हैं, और फ़ाइलें बाइट्स को बिना हस्ताक्षरित मानों के रूप में संग्रहीत करती हैं। यही कारण है कि read() $ एफएफ के लिए -1 के बजाय 255 देने के लिए एक int - देता है। write(int) के साथ, आप एक बाइट में $ 25 के रूप में $ एफएफ स्टोर नहीं कर सकते हैं।

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