c# - কোন বস্তু একটি বাইটে রূপান্তর করুন




.net object (9)

অন্যদের আগে যেমন বলা হয়েছে, আপনি বাইনারি সিরিয়ালাইজেশান ব্যবহার করতে পারেন, কিন্তু এটি অতিরিক্ত বাইট তৈরি করতে পারে বা একই রকম তথ্য না দিয়ে কোনও বস্তুর মধ্যে ডেসারয়ালাইজড হতে পারে। অন্য দিকে প্রতিফলন ব্যবহার বেশ জটিল এবং খুব ধীর। আরেকটি সমাধান যা কঠোরভাবে আপনার বস্তুর বাইট এবং vise বিপরীত রূপান্তর করতে পারেন - মার্শালিং:

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);

ক্ষেত্রের দ্বারা আপনার নিজের সিরিয়ালাইজেশন ক্ষেত্রের তুলনায় ছোট বস্তু এবং structs এর জন্য এই পদ্ধতিটি ব্যবহারযোগ্যভাবে ধীর এবং আংশিকভাবে অনিরাপদ। (কারণ অননুমোদিত মেমরি থেকে দুবার অনুলিপি করার কারণে), তবে সিরিয়ালাইজেশান বাস্তবায়ন না করে বস্তুকে বাইটে রূপান্তর করতে সহজতম উপায় এবং ছাড়া [Serializable] বৈশিষ্ট্য।

আমি একটি প্রোটোটাইপ টিসিপি সংযোগ লিখছি এবং আমি পাঠানো তথ্য homogenizing কিছু সমস্যা হচ্ছে।

এই মুহূর্তে, আমি স্ট্রিং ছাড়া কিছুই পাঠাচ্ছি না, কিন্তু ভবিষ্যতে আমরা কোনও বস্তু পাঠাতে সক্ষম হতে চাই।

এই মুহুর্তে কোডটি বেশ সহজ, কারণ আমি মনে করি সবকিছু বাইট অ্যারের মধ্যে নিক্ষেপ করা যেতে পারে:

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 ){...}

সমস্যাটি হল, যদি আমি এটি করি তবে আমার প্রতিটি ধরনের বস্তুর জন্য পরীক্ষা করতে হবে যা রানটাইমতে বাইট [] তে ঢোকানো যাবে না।

যেহেতু আমি প্রতিটি বস্তুকে জানি না যা রানটাইম এ বাইট [] তে ঢোকানো যাবে না, এটি আসলে একটি বিকল্প নয়।

কিভাবে C # .NET 4.0 এ একটি বাইট অ্যারের মধ্যে কোনও বস্তুর রূপান্তর করে?


আপনি খুঁজছেন কি সিরিয়ালাইজেশন হয়। নেট প্ল্যাটফর্মের জন্য সিরিয়ালাইজেশন এর বিভিন্ন রূপ রয়েছে


আমি বরং "বাইট মধ্যে ঢালাই" অভিব্যক্তি "সিরিয়ালাইজেশন" ব্যবহার করতে চাই। একটি বস্তুর ক্রমবর্ধমান মানে এটি একটি বাইট অ্যারে (বা এক্সএমএল, বা অন্য কিছু) রূপান্তর করা হয় যা অবজেক্টটি পুনঃনির্মাণ করতে রিমোট বাক্সে ব্যবহার করা যেতে পারে। .NET এ, Serializable এ্যাট্রিবিউট এমন ধরণের চিহ্ন চিহ্নিত করে যার বস্তুগুলি সিরিয়ালাইজ করা যায়।


এই নিবন্ধটি চেকআউট http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html : 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;
}

এক্সটেনশন ক্লাসে সম্মিলিত সমাধান:

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);
   }

}

কিভাবে serialization সম্পর্কে? here একটি চেহারা নিতে।


বস্তু বাইট অ্যারে রূপান্তর বিকল্প উপায়:

    TypeConverter objConverter = TypeDescriptor.GetConverter(objMsg.GetType());
    byte[] data = (byte[])objConverter.ConvertTo(objMsg, typeof(byte[]));

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 (এবং obj সকল বৈশিষ্ট্য / ক্ষেত্রের জন্য) এটিকে Serializable এট্রিবিউটের সাথে ট্যাগ করা দরকার যাতে সফলভাবে Serializable সাথে Serializable করা যায়।


public static class SerializerDeserializerExtensions
{
    public static byte[] Serializer(this object _object)
    {   
        byte[] bytes;
        using (var _MemoryStream = new MemoryStream())
        {
            IFormatter _BinaryFormatter = new BinaryFormatter();
            _BinaryFormatter.Serialize(_MemoryStream, _object);
            bytes = _MemoryStream.ToArray();
        }
        return bytes;
    }

    public static T Deserializer<T>(this byte[] _byteArray)
    {   
        T ReturnValue;
        using (var _MemoryStream = new MemoryStream(_byteArray))
        {
            IFormatter _BinaryFormatter = new BinaryFormatter();
            ReturnValue = (T)_BinaryFormatter.Deserialize(_MemoryStream);    
        }
        return ReturnValue;
    }
}

আপনি নীচের কোড মত এটি ব্যবহার করতে পারেন।

        DataTable _DataTable = new DataTable();
        _DataTable.Columns.Add(new DataColumn("Col1"));
        _DataTable.Columns.Add(new DataColumn("Col2"));
        _DataTable.Columns.Add(new DataColumn("Col3"));

        for (int i = 0; i < 10; i++) {
            DataRow _DataRow = _DataTable.NewRow();
            _DataRow["Col1"] = (i + 1) + "Column 1";
            _DataRow["Col2"] = (i + 1) + "Column 2";
            _DataRow["Col3"] = (i + 1) + "Column 3";
            _DataTable.Rows.Add(_DataRow);
        }

        byte[] ByteArrayTest =  _DataTable.Serializer();
        DataTable dt = ByteArrayTest.Deserializer<DataTable>();




byte