2008-09-26 13 views
18

पर समान लेकिन संशोधित ऑब्जेक्ट भेजना मेरे पास निम्न कोड है जो या तो मेरे हिस्से पर एक बग या गलतफहमी दिखाता है।ऑब्जेक्टऑटपुटस्ट्रीम

मैंने एक ही सूची भेजी, लेकिन ऑब्जेक्टऑटपुटस्ट्रीम पर संशोधित किया। एक बार [0] और अन्य [1] के रूप में। लेकिन जब मैं इसे पढ़ता हूं, तो मुझे दो बार [0] मिलता है। मुझे लगता है कि यह इस तथ्य के कारण होता है कि मैं एक ही ऑब्जेक्ट पर भेज रहा हूं और ऑब्जेक्टऑटपुटस्ट्रीम उन्हें किसी भी तरह कैशिंग कर रहा है।

क्या यह काम करना चाहिए, या मुझे एक बग फाइल करना चाहिए?

 
import java.io.*; 
import java.net.*; 
import java.util.*; 

public class OOS { 

    public static void main(String[] args) throws Exception { 
     Thread t1 = new Thread(new Runnable() { 
      public void run() { 
       try { 
        ServerSocket ss = new ServerSocket(12344); 
        Socket s= ss.accept(); 

        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); 
        List same = new ArrayList(); 
        same.add(0); 
        oos.writeObject(same); 
        same.clear(); 
        same.add(1); 
        oos.writeObject(same); 

       } catch(Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     t1.start(); 

     Socket s = new Socket("localhost", 12344); 
     ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); 

     // outputs [0] as expected 
     System.out.println(ois.readObject()); 

     // outputs [0], but expected [1] 
     System.out.println(ois.readObject()); 
     System.exit(0); 
    } 
} 

उत्तर

24

धारा एक संदर्भ ग्राफ है, तो एक वस्तु जो दो बार भेज दिया जाता है दूसरे छोर पर दो वस्तुओं नहीं देंगे, आप केवल एक मिल जाएगा। और एक ही ऑब्जेक्ट को दो बार अलग से भेजना आपको एक ही उदाहरण दो बार देगा (प्रत्येक एक ही डेटा के साथ - जो आप देख रहे हैं)।

यदि आप ग्राफ़ को रीसेट करना चाहते हैं तो रीसेट() विधि देखें।

-3

क्या आप शायद चाहते हैं:

ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); 
List same = new ArrayList(); 
same.add(0); 
oos.writeObject(same); 
oos.flush(); // flush the stream here 
same.clear(); 
same.add(1); 
oos.writeObject(same); 

अन्यथा एक ही वस्तु दो बार जब धारा बंद कर दिया है या उसके बफर खत्म प्लावित कर दिया जाएगा।

बस एफवाईआई, जब आप ऑब्जेक्ट्स को deserialize करते हैं, तो मान लें कि o1 और o2, o1 != o2

+0

नहीं, जिसने इसे हल नहीं किया, मैक्स सही था, रीसेट का उपयोग करें() – Pyrolistical

+0

यह काम नहीं करता है। 'फ्लश()' में यहां जादुई गुण नहीं हैं। – EJP

6

मैक्स सही है, लेकिन आप भी उपयोग कर सकते हैं:

public void writeUnshared(Object obj); 

चेतावनी

+2

यह इस मामले में काम करेगा, लेकिन आम तौर पर वास्तव में अजीब त्रुटियों का कारण बन जाएगा। लिखे गए किसी भी घटक वस्तु को अभी भी साझा किया जाएगा। तो उदाहरण के लिए यदि उपरोक्त सूची संग्रह। सिंक्रनाइज़लिस्ट के साथ लपेटा गया था, तो समस्या बनी रहेगी। लिखना बहुत उपयोगी नहीं है। –

0

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

public void reset() throws IOException 

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

+0

ऑब्जेक्ट ग्राफ़ को संरक्षित करने के डिजाइन उद्देश्य को दिया गया यह एकमात्र संभव डिज़ाइन है। – EJP

+0

[यहां] (https://stackoverflow.com/a/8956926/207421) से चोरी की गई। – EJP