2012-09-09 21 views
11

अपडेट नहीं करेगा मैं थोड़ा सॉकेट आधारित प्रोग्राम लिख रहा हूं। मैं सॉकेट के माध्यम से जानकारी पास करने के लिए क्लास मॉडलवेन्ट का उपयोग कर रहा हूं। ModelEvent के अंदर, प्रकार (ऑब्जेक्ट) के एक चरणीय यद्यपि है।जावा सॉकेट/क्रमबद्धता, ऑब्जेक्ट

ऑब्जेक्ट स्वयं कुछ मानों के साथ 2 डी-सरणी है।

object[1][2] = 2; 
ModelEvent event = new ModelEvent("allo", object); 
dispatchEvent(event); 

object[2][3] = 2; 
ModelEvent event2 = new ModelEvent("you", object); 
dispatchEvent(event2); 

मान लें कि सरणी वस्तु मान 1 पहली घटना (घटना) ग्राहक द्वारा प्राप्त होता है से भर जाता है, और डेटा सही है। दूसरी घटना भेजी गई हालांकि डेटा सही नहीं है। इसका डेटा पहले प्रेषण जैसा ही है। "एलो" और "आप" यह देखना है कि मैं एक ही घटना को दो बार नहीं पढ़ रहा हूं और इसका उत्तर नहीं है। स्ट्रिंग सही है, लेकिन ऑब्जेक्ट नहीं है, अगर यह अद्यतन किया गया है तो घटना नहीं है। मैं दूसरी घटना भेजने से पहले सरणी के माध्यम से पुनरावृत्ति करता हूं यह देखने के लिए कि क्या यह सर्वर की ओर से अपडेट किया गया है, और यह है। लेकिन ग्राहक पक्ष पर, यह अभी भी पहले प्रेषण जैसा ही रहता है, भले ही ईवेंट स्वयं बदल जाए।

+0

आप इसे क्लाइंट साइड पर कैसे पढ़ रहे हैं? –

+0

ऑब्जेक्टइनपुटस्ट्रीम.readObject और मैंने इसे – maniak

उत्तर

20

ObjectOutputStream.reset देखें।

रीसेट स्ट्रीम में पहले से लिखे गए किसी भी ऑब्जेक्ट की स्थिति को अवहेलना करेगा। राज्य को ObjectOutputStream के समान ही रीसेट किया गया है। स्ट्रीम में वर्तमान बिंदु को रीसेट के रूप में चिह्नित किया गया है, इसलिए इसी बिंदु पर संबंधित ObjectInputStream रीसेट किया जाएगा। पहले स्ट्रीम में लिखे गए ऑब्जेक्ट्स को स्ट्रीम में पहले से ही नहीं दिया जाएगा। वे फिर से स्ट्रीम में लिखे जाएंगे। सुनिश्चित करने के लिए अपने अद्यतन राज्य धारावाहिक है एक ही वस्तु लिखने से पहले

/* prevent using back references */ 
output.reset(); 
output.writeObject(...); 

कॉल रीसेट। अन्यथा, यह केवल बैक संदर्भ का उपयोग पहले से लिखे गए ऑब्जेक्ट में पूर्व-दिनांकित स्थिति के साथ करेगा।

या, आप वैकल्पिक रूप से ObjectOutputStream.writeUnshared का उपयोग निम्नानुसार कर सकते हैं।

ObjectOutputStream पर "unshared" ऑब्जेक्ट लिखता है। यह विधि writeObject के समान है, सिवाय इसके कि यह हमेशा दिए गए ऑब्जेक्ट को धारा में एक नई, अद्वितीय वस्तु के रूप में लिखता है (जैसा कि पहले क्रमबद्ध उदाहरण के लिए इंगित बैक-रेफरेंस के विपरीत है)।

विशेष रूप से:

  • writeUnshared के माध्यम से लिखा एक वस्तु हमेशा एक नव प्रदर्शित होने वस्तु (एक वस्तु है जो अभी तक धारा में लिखा नहीं गया है) के रूप में एक ही तरीके से धारावाहिक है, की परवाह किए बिना या नहीं, ऑब्जेक्ट पहले लिखा गया है।

  • यदि writeObject किसी ऑब्जेक्ट को लिखने के लिए उपयोग किया जाता है जिसे पहले लिखा गया था, तो पिछले लिखने के लिए पहले ऑपरेशन का मानना ​​है कि यह एक अलग वस्तु का लेखन था। दूसरे शब्दों में, ObjectOutputStream कभी भी writeUnshared पर कॉल द्वारा लिखे गए ऑब्जेक्ट डेटा के बैक-रेफरेंस उत्पन्न नहीं करेगा।

जबकि writeUnshared के माध्यम से एक वस्तु लेखन अपने आप में नहीं है वस्तु के लिए एक अनूठा संदर्भ गारंटी जब यह deserialized है, यह एक वस्तु एक धारा में कई बार परिभाषित किया जा करने की अनुमति देता है, तो द्वारा readUnshared करने के लिए कि कई कॉल रिसीवर संघर्ष नहीं करेगा।ध्यान दें कि ऊपर वर्णित नियम केवल writeUnshared के साथ लिखे गए बेस-स्तरीय ऑब्जेक्ट पर लागू होते हैं, और ऑब्जेक्ट ग्राफ़ में किसी भी पारदर्शी संदर्भित उप-ऑब्जेक्ट्स को क्रमबद्ध करने के लिए नहीं।

output.writeUnshared(...); 

नोट यह ObjectInputStream.readUnshared साथ जोड़ी को यह अच्छी आदत है।

ObjectInputStream से "unshared" ऑब्जेक्ट पढ़ता है। यह विधि readObject के समान है, सिवाय इसके कि यह readObject और readUnshared पर कॉल को इस कॉल के माध्यम से प्राप्त deserialized आवृत्ति के अतिरिक्त संदर्भ लौटने से रोकती है।

विशेष रूप से: एक बैक-संदर्भ (एक वस्तु जो धारा को पहले से लिखा गया है की धारा प्रतिनिधित्व) deserialize करने के लिए कहा जाता है

  • हैं readUnshared, एक ObjectStreamException
  • हैं readUnshared रिटर्न फेंक दिया जाएगा सफलतापूर्वक, फिर readUnshared द्वारा deserialized धारा संभाल के बैक-रेफरेंस को deserialize करने के बाद के प्रयासों को ObjectStreamException फेंक दिया जाएगा।

readUnshared के माध्यम से किसी ऑब्जेक्ट को Deserializing लौटा ऑब्जेक्ट से जुड़े स्ट्रीम हैंडल को अमान्य करता है। ध्यान दें कि यह हमेशा गारंटी नहीं देता है कि readUnshared द्वारा वापस संदर्भ अद्वितीय है; deserialized ऑब्जेक्ट readResolve विधि को परिभाषित कर सकता है जो किसी अन्य ऑब्जेक्ट को दिखाई देने वाली ऑब्जेक्ट देता है, या पढ़ा गया है, Class ऑब्जेक्ट या enum स्ट्रीम में या बाह्य माध्यमों के माध्यम से लगातार कहीं और उपलब्ध हो सकता है। यदि deserialized ऑब्जेक्ट readResolve विधि को परिभाषित करता है और उस विधि का आविष्कार एक सरणी देता है, तो readUnshared उस सरणी का उथला क्लोन देता है; यह गारंटी देता है कि लौटाए गए सरणी ऑब्जेक्ट अद्वितीय है और readObject के आमंत्रण से दूसरी बार प्राप्त नहीं किया जा सकता है या ObjectInputStream पर पढ़ा गया है, भले ही अंतर्निहित डेटा स्ट्रीम का उपयोग किया गया हो।

obj = input.readUnshared(); 
+1

डाला है, मैं अभी आपको चुंबन देना चाहता हूं! * कोई होम * धन्यवाद। बस समझने के लिए, जब किसी ऑब्जेक्ट को स्ट्रीम में दो बार भेजा जाता है, तो यह अपने पिछले राज्य को याद रखता है और पुराने का उपयोग करता है? – maniak

+0

हां यह करता है :)! मुझे लगता है कि यह प्रदर्शन कारणों के लिए है, लेकिन यह उस उपयोग के अनुरूप नहीं है जिसे आप बनाना चाहते हैं। प्रदर्शन प्रभाव को इंगित करने के लिए – Flawyte

3

मैं dispatchEvent कोड नहीं दिख रहा है, लेकिन आप क्या लिखा से मैं निम्नलिखित मान: आप एक ही वस्तु लिखने (केवल अपने राज्य परिवर्तित), इसका मतलब है कि यह केवल संदर्भ में दो बार लिखेंगे । आप जावा आउटपुट स्ट्रीम डॉक्स (प्रदर्शन के लिए) में देख सकते हैं।

आप writeUnshared() का उपयोग करना चाहिए, प्रत्येक लिखने

पर मैं देख रहा हूँ रीसेट सुझाव दिया गया था, इस एक ही परिणाम के लिए आपको मिल जाएगा, लेकिन यह प्रदर्शन प्रभाव पड़ता है जो एक नई वस्तु बनाने होंगे।

+0

+1। जब आप पोस्ट करते थे तो मैं 'writeUnshared' को शामिल करने के लिए अपना उत्तर संशोधित कर रहा था। 'प्रदर्शन प्रभाव' के लिए – oldrinb

+1

-1। WriteUnared() और रीसेट()/writeObject() के बीच एकमात्र अंतर यह है कि पहले मामले में संदर्भित ऑब्जेक्ट्स को अभी भी हैंडल के रूप में भेजा जा सकता है।यह एक प्रमुख * कार्यात्मक * अंतर है, और ऐसा नहीं हो सकता कि ओपी बिल्कुल क्या चाहता है। केवल 'प्रदर्शन प्रभाव' के लिए सभी को कम करना पूरी तरह से गलत और पूरी तरह से भ्रामक है। – EJP

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