2010-07-29 17 views
20

java.nio.ByteBuffer#duplicate() की एक नई बाइट बफर लौटाता है जो पुरानी बफर की सामग्री साझा करता है। पुराने बफर की सामग्री में परिवर्तन नए बफर में दिखाई देंगे, और इसके विपरीत। अगर मैं बाइट बफर की गहरी प्रतिलिपि चाहता हूं तो क्या होगा?जावा की बाइटबफर

उत्तर

1

आपको पूरे बफर को फिर से शुरू करने और नए बफर में मूल्य द्वारा कॉपी करने की आवश्यकता होगी।

+3

'put' विधि का एक (वैकल्पिक) अधिभार है जो आपके लिए यह करता है। – nos

+0

वाहू! मैंने कुछ नया सीखा। – Kylar

35

मुझे लगता है कि गहरी प्रति में byte[] शामिल नहीं होना चाहिए। निम्नलिखित का प्रयास करें:

public static ByteBuffer clone(ByteBuffer original) { 
     ByteBuffer clone = ByteBuffer.allocate(original.capacity()); 
     original.rewind();//copy from the beginning 
     clone.put(original); 
     original.rewind(); 
     clone.flip(); 
     return clone; 
} 
+0

मुझे क्लोन को फ़्लिप करने की आवश्यकता क्यों है? तो सीमा मेरी असली क्षमता – Karussell

+0

वाह से कम है! वह सहायक था। धन्यवाद! –

+2

इस मामले में कॉपी की गई एकमात्र चीज निशान नहीं है, इसलिए बस पता करें कि यदि आप चिह्न का उपयोग करते हैं तो यह खो जाएगा। साथ ही, यह फ़ंक्शन केवल शुरुआत से सीमा तक प्रतिलिपि बनाता है और मूल की स्थिति खो जाती है, मैं स्थिति = 0 और सीमा = क्षमता सेटिंग सेट करने और उन्हें लौटने से पहले मूल और क्लोन पर रीसेट करने के लिए टेम्पप वर्र्स के रूप में संग्रहीत करने का सुझाव दूंगा। इसके अलावा रिवाइंड मार्क को छोड़ देता है ताकि इसका उपयोग शायद एक अच्छा विचार न हो। मैं एक और पूर्ण विधि के साथ एक उत्तर पोस्ट करूंगा। – LINEMAN78

2

mingfai के समाधान के बंद आधार पर:

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

public static ByteBuffer deepCopy(ByteBuffer orig) 
{ 
    int pos = orig.position(), lim = orig.limit(); 
    try 
    { 
     orig.position(0).limit(orig.capacity()); // set range to entire buffer 
     ByteBuffer toReturn = deepCopyVisible(orig); // deep copy range 
     toReturn.position(pos).limit(lim); // set range to original 
     return toReturn; 
    } 
    finally // do in finally in case something goes wrong we don't bork the orig 
    { 
     orig.position(pos).limit(lim); // restore original 
    } 
} 

public static ByteBuffer deepCopyVisible(ByteBuffer orig) 
{ 
    int pos = orig.position(); 
    try 
    { 
     ByteBuffer toReturn; 
     // try to maintain implementation to keep performance 
     if(orig.isDirect()) 
      toReturn = ByteBuffer.allocateDirect(orig.remaining()); 
     else 
      toReturn = ByteBuffer.allocate(orig.remaining()); 

     toReturn.put(orig); 
     toReturn.order(orig.order()); 

     return (ByteBuffer) toReturn.position(0); 
    } 
    finally 
    { 
     orig.position(pos); 
    } 
} 
+0

'बफर # isDirect() 'सार्वजनिक रूप से उपलब्ध होने पर आपको कक्षा के नाम की जांच क्यों की आवश्यकता है? – seh

+0

अच्छा बिंदु, उस विधि के बारे में भूल गया। अपडेट करूंगी। – LINEMAN78

15

इस सवाल अभी भी एक ByteBuffer को कॉपी करने के लिए पहली हिट में से एक के रूप में आता है, मैं अपने समाधान की पेशकश करेगा। यह समाधान किसी भी मार्क सेट सहित मूल बफर को स्पर्श नहीं करता है, और मूल की समान क्षमता के साथ एक गहरी प्रतिलिपि वापस करेगा।

clone.position(original.position()); 
clone.limit(original.limit()); 
clone.order(original.order()); 
return clone; 
+1

मध्यवर्ती 'बाइट' सरणी के बजाय' clone.put (readOnlyCopy) 'क्यों नहीं? – seh

+0

@seh क्योंकि मैं मूर्ख था और उस विधि को नहीं देखा। इस पर ध्यान दिलाने के लिए धन्यवाद। – jdmichal

+0

यह सबसे अच्छा समाधान है। यह मूल सामग्री को म्यूटेट नहीं करता है और एक ही चीज़ करने के लिए सबसे साफ तरीके प्रदान करता है। –

2

एक और सरल उपाय

:

public static ByteBuffer cloneByteBuffer(final ByteBuffer original) { 
    // Create clone with same capacity as original. 
    final ByteBuffer clone = (original.isDirect()) ? 
     ByteBuffer.allocateDirect(original.capacity()) : 
     ByteBuffer.allocate(original.capacity()); 

    // Create a read-only copy of the original. 
    // This allows reading from the original without modifying it. 
    final ByteBuffer readOnlyCopy = original.asReadOnlyBuffer(); 

    // Flip and read from the original. 
    readOnlyCopy.flip(); 
    clone.put(readOnlyCopy); 

    return clone; 
} 

एक स्थान, सीमा, या आदेश मूल रूप में ही स्थापित किया जाना के लिए परवाह है, तो उस से ऊपर के लिए एक आसान अलावा है

public ByteBuffer deepCopy(ByteBuffer source, ByteBuffer target) { 

    int sourceP = source.position(); 
    int sourceL = source.limit(); 

    if (null == target) { 
     target = ByteBuffer.allocate(source.remaining()); 
    } 
    target.put(source); 
    target.flip(); 

    source.position(sourceP); 
    source.limit(sourceL); 
    return target; 
} 
संबंधित मुद्दे