c# - किसी ऑब्जेक्ट को बाइट में कनवर्ट करें




.net object (8)

Serialization के बारे में कैसे? here एक नज़र डालें।

मैं एक प्रोटोटाइप टीसीपी कनेक्शन लिख रहा हूं और मुझे भेजे जाने वाले डेटा को होमोजेनाइज करने में कुछ परेशानी हो रही है।

फिलहाल, मैं तारों के अलावा कुछ भी नहीं भेज रहा हूं, लेकिन भविष्य में हम किसी वस्तु को भेजने में सक्षम होना चाहते हैं।

इस समय कोड काफी सरल है, क्योंकि मैंने सोचा था कि सबकुछ बाइट सरणी में डाला जा सकता है:

void SendData(object headerObject, object bodyObject)
{
  byte[] header = (byte[])headerObject;  //strings at runtime, 
  byte[] body = (byte[])bodyObject;      //invalid cast exception

  // Unable to cast object of type 'System.String' to type 'System.Byte[]'.
  ...
}

यह निश्चित रूप से आसानी से हल किया गया है

if( state.headerObject is System.String ){...}

समस्या यह है कि, अगर मैं इसे इस तरह से करता हूं, तो मुझे प्रत्येक प्रकार की ऑब्जेक्ट की जांच करने की आवश्यकता होती है जिसे रनटाइम पर बाइट [] में नहीं डाला जा सकता है।

चूंकि मैं प्रत्येक वस्तु को नहीं जानता जिसे रनटाइम पर बाइट [] में नहीं डाला जा सकता है, यह वास्तव में एक विकल्प नहीं है।

सी # .NET 4.0 में किसी ऑब्जेक्ट को बाइट सरणी में कैसे परिवर्तित करता है?


आप जो खोज रहे हैं वह क्रमबद्ध है। .NET मंच के लिए serialization के कई रूप उपलब्ध हैं


इस आलेख को चेकआउट करें: http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html

नीचे दिए गए कोड का प्रयोग करें

// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
    if(obj == null)
        return null;

    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    bf.Serialize(ms, obj);

    return ms.ToArray();
}

// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
{
    MemoryStream memStream = new MemoryStream();
    BinaryFormatter binForm = new BinaryFormatter();
    memStream.Write(arrBytes, 0, arrBytes.Length);
    memStream.Seek(0, SeekOrigin.Begin);
    Object obj = (Object) binForm.Deserialize(memStream);

    return obj;
}

इस तरह कुछ सरल कैसे है?

return ((object[])value).Cast<byte>().ToArray(); 

जैसा कि दूसरों ने पहले कहा है, आप बाइनरी सीरियलाइजेशन का उपयोग कर सकते हैं, लेकिन यह एक अतिरिक्त बाइट उत्पन्न कर सकता है या एक ऑब्जेक्ट में deserialized हो सकता है जिसमें बिल्कुल डेटा नहीं है। दूसरी तरफ प्रतिबिंब का उपयोग काफी जटिल और बहुत धीमा है। एक और समाधान है जो आपकी वस्तुओं को बाइट्स और vise-versa में कड़ाई से रूपांतरित कर सकता है - marshalling:

var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(your_object, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);

और बाइट्स को ऑब्जेक्ट में कनवर्ट करने के लिए:

var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);

यह छोटे-छोटे ऑब्जेक्ट्स और स्ट्रक्चर के लिए इस दृष्टिकोण का उपयोग करने के लिए उल्लेखनीय रूप से धीमा और आंशिक रूप से असुरक्षित है (क्षेत्र से अपने स्वयं के क्रमिकरण क्षेत्र की तुलना में (दोहरी प्रतिलिपि से / अप्रबंधित स्मृति की वजह से), लेकिन ऑब्जेक्ट को सख्ती से लागू करने के बिना ऑब्जेक्ट को बाइट [] में कड़ाई से परिवर्तित करने का सबसे आसान तरीका है और बिना [Serializable] विशेषता।


मैं बजाय "बाइट्स में कास्टिंग" की तुलना में "क्रमबद्धता" अभिव्यक्ति का उपयोग करूंगा। ऑब्जेक्ट को सीरियलाइज़ करना मतलब है कि इसे बाइट सरणी (या एक्सएमएल, या कुछ और) में परिवर्तित करना जिसका उपयोग रिमोट बॉक्स पर ऑब्जेक्ट को फिर से बनाने के लिए किया जा सकता है। .NET में, Serializable विशेषता अंक प्रकार जिनकी वस्तुओं को क्रमबद्ध किया जा सकता है।

चीयर्स, मथियास


विस्तार वर्ग में संयुक्त समाधान:

public static class Extensions {

    public static byte[] ToByteArray(this object obj) {
        var size = Marshal.SizeOf(data);
        var bytes = new byte[size];
        var ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(data, ptr, false);
        Marshal.Copy(ptr, bytes, 0, size);
        Marshal.FreeHGlobal(ptr);
        return bytes;
   }

    public static string Serialize(this object obj) {
        return JsonConvert.SerializeObject(obj);
   }

}

BinaryFormatter प्रयोग करें:

byte[] ObjectToByteArray(object obj)
{
    if(obj == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

ध्यान दें कि obj और obj भीतर किसी भी गुण / फ़ील्ड (और उनके सभी गुणों / फ़ील्ड के लिए ऑन-ऑन) को सभी को सफलतापूर्वक क्रमबद्ध करने के लिए Serializable विशेषता के साथ टैग करने की आवश्यकता होगी।





byte