프로토 타입 TCP 연결을 작성 중이며 전송할 데이터를 균질화하는 데 문제가 있습니다.
현재는 문자열 만 보내지 않지만 앞으로는 개체를 보낼 수 있기를 원합니다.
모든 것이 바이트 배열로 캐스팅 될 수 있다고 생각했기 때문에 코드는 현재 매우 간단합니다.
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 ){...}
문제는 내가 그렇게하면 런타임에 byte []로 캐스팅 할 수없는 모든 유형의 객체를 확인해야한다는 것입니다.
런타임에 byte []로 캐스팅 할 수없는 모든 객체를 알지 못하기 때문에 이것은 실제로 옵션이 아닙니다.
C # .NET 4.0에서 객체를 바이트 배열로 어떻게 변환합니까?
답변
사용하십시오 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
속성을 성공적으로 직렬화한다.
답변
이 기사를 확인하십시오 : 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;
}
답변
다른 사람들이 이전에 말했듯이 이진 직렬화를 사용할 수는 있지만 여분의 바이트를 생성하거나 정확히 동일한 데이터가 아닌 객체로 직렬화 해제 할 수 있습니다. 반면에 반사를 사용하는 것은 매우 복잡하고 매우 느립니다. 객체를 바이트로 변환하고 마샬링하는 다른 솔루션이 있습니다.
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);
작은 객체에 대해이 접근 방식을 사용하는 것은 눈에 띄게 느리고 부분적으로 안전하지 않으며 (관리되지 않은 메모리에서 이중 복사로 인해 필드별로 자신의 직렬화와 비교하여) 직렬화를 구현하지 않고 객체를 바이트 []로 엄격하게 변환하는 가장 쉬운 방법입니다. 그리고 [직렬화 가능] 속성이 없습니다.
답변
당신이 찾고있는 것은 직렬화입니다. .Net 플랫폼에 사용 가능한 몇 가지 직렬화 형식이 있습니다.
답변
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>();
답변
을 사용하는 Encoding.UTF8.GetBytes
것보다을 사용하는 것이 더 빠릅니다 MemoryStream
. 여기서는 NewtonsoftJson 을 사용하여 입력 객체를 JSON 문자열로 변환 한 다음 JSON 문자열에서 바이트를 가져옵니다.
byte[] SerializeObject(object value) =>Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));
이 버전의 @Daniel DiPaolo 버전 벤치 마크
Method | Mean | Error | StdDev | Median | Gen 0 | Allocated |
--------------------------|----------|-----------|-----------|----------|--------|-----------|
ObjectToByteArray | 4.983 us | 0.1183 us | 0.2622 us | 4.887 us | 0.9460 | 3.9 KB |
ObjectToByteArrayWithJson | 1.548 us | 0.0309 us | 0.0690 us | 1.528 us | 0.3090 | 1.27 KB |
답변
확장 클래스의 결합 솔루션 :
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);
}
}