c#中如何将类转换为byte[]

shuihan20e 2014-01-21 10:53:49

public class tmsghead
{
public char[] MsgCode;
public char[] Sender;
public char[] Recver;

public tmsghead()
{
MsgCode = new char[2];
Sender = new char[6];
Recver = new char[6];
}
}

有个BitConverter.GetBytes方法,但是没有针对char[]的,难道要循环吗?如果把成员里转换成byte[]拼到一起呢?
...全文
2365 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2014-01-22
  • 打赏
  • 举报
回复
呵呵,二进制直接序列化你不喜欢,那么就给你一个你喜欢滴 class的原始定义

     [StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi)]

       public class testA
        {
           [MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]
          public char[] A;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
          public char[] B ;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public char[] C;
        }
封送到byte[]的过程
       testA a=new testA();
            a.A="aa".ToCharArray();
            a.B="bbbbbb".ToCharArray();
            a.C="cccccc".ToCharArray();
           int res= Marshal.SizeOf(typeof(testA));
           byte[] b_array = new byte[res];
           IntPtr buff = System.Runtime.InteropServices.Marshal.AllocHGlobal(res);
           System.Runtime.InteropServices.Marshal.StructureToPtr(a, buff, true);
           System.Runtime.InteropServices.Marshal.Copy(buff, b_array, 0, res);
           System.Runtime.InteropServices.Marshal.FreeHGlobal(buff);
最终滴b_array就是你要滴
Luckeryin 2014-01-22
  • 打赏
  • 举报
回复
为什么不考虑用JSON格式来传递你的类呢?
wanghui0380 2014-01-22
  • 打赏
  • 举报
回复
这个建议使用结构体,并标记好内存分布大小 至于class,如果是固定长度,请先定义char[]滴长度,否则请直接换用string来表示 ps:class可以做二进制序列化
xian_wwq 2014-01-22
  • 打赏
  • 举报
回复
序列化比较方便,但用自定义的流可控且效率更高
shuihan20e 2014-01-22
  • 打赏
  • 举报
回复
引用 8 楼 wyd1520 的回复:
你是不是要转成C++的结构体。。。。
又见马桶猫 不准结构体了,改传对象了,结构体问题已解决,现在想传对象,发现序列化不行,改用流了
ayahime 2014-01-22
  • 打赏
  • 举报
回复
可以尝试一下protobuf-net
shuihan20e 2014-01-22
  • 打赏
  • 举报
回复
引用 12 楼 Luckeryin 的回复:
为什么不考虑用JSON格式来传递你的类呢?
用这个需要修改服务器端成本过高
shuihan20e 2014-01-22
  • 打赏
  • 举报
回复
引用 13 楼 wanghui0380 的回复:
呵呵,二进制直接序列化你不喜欢,那么就给你一个你喜欢滴 class的原始定义

     [StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi)]

       public class testA
        {
           [MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]
          public char[] A;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
          public char[] B ;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public char[] C;
        }
封送到byte[]的过程
       testA a=new testA();
            a.A="aa".ToCharArray();
            a.B="bbbbbb".ToCharArray();
            a.C="cccccc".ToCharArray();
           int res= Marshal.SizeOf(typeof(testA));
           byte[] b_array = new byte[res];
           IntPtr buff = System.Runtime.InteropServices.Marshal.AllocHGlobal(res);
           System.Runtime.InteropServices.Marshal.StructureToPtr(a, buff, true);
           System.Runtime.InteropServices.Marshal.Copy(buff, b_array, 0, res);
           System.Runtime.InteropServices.Marshal.FreeHGlobal(buff);
最终滴b_array就是你要滴
感谢,回头试下,我以为只有结构体才能这样用,原来类也这可以这样用啊
超纯の小白兔 2014-01-21
  • 打赏
  • 举报
回复
需要把这个类设置为可序列化
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace Model
{

    public class SerializationUnit
    {
        /// <summary>  
        /// 把对象序列化为字节数组  
        /// </summary>  
        public static byte[] SerializeObject(object obj)
        {
            if (obj == null)
                return null;
            //内存实例
            MemoryStream ms = new MemoryStream();
            //创建序列化的实例
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);//序列化对象,写入ms流中  
            ms.Position = 0;
            //byte[] bytes = new byte[ms.Length];//这个有错误
            byte[] bytes = ms.GetBuffer();
            ms.Read(bytes, 0, bytes.Length);
            ms.Close();
            return bytes;
        }

        /// <summary>  
        /// 把字节数组反序列化成对象  
        /// </summary>  
        public static object DeserializeObject(byte[] bytes)
        {
            object obj = null;
            if (bytes == null)
                return obj;
            //利用传来的byte[]创建一个内存流
            MemoryStream ms = new MemoryStream(bytes);
            ms.Position = 0;
            BinaryFormatter formatter = new BinaryFormatter();
            obj = formatter.Deserialize(ms);//把内存流反序列成对象  
            ms.Close();
            return obj;
        }
        /// <summary>
        /// 把字典序列化
        /// </summary>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static byte[] SerializeDic(Dictionary<string, object> dic)
        {
            if (dic.Count == 0)
                return null;
            MemoryStream ms = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, dic);//把字典序列化成流

            byte[] bytes = new byte[ms.Length];//从流中读出byte[]
            ms.Read(bytes, 0, bytes.Length);

            return bytes;
        }
        /// <summary>
        /// 反序列化返回字典
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Dictionary<string, object> DeserializeDic(byte[] bytes)
        {
            Dictionary<string, object> dic = null;
            if (bytes == null)
                return dic;
            //利用传来的byte[]创建一个内存流
            MemoryStream ms = new MemoryStream(bytes);
            ms.Position = 0;
            BinaryFormatter formatter = new BinaryFormatter();
            //把流中转换为Dictionary
            dic = (Dictionary<string, object>)formatter.Deserialize(ms);
            return dic;
        }
    }

}
破碎的脸 2014-01-21
  • 打赏
  • 举报
回复
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

public class App 
{
    [STAThread]
    static void Main() 
    {
        Serialize();
        Deserialize();
    }

    static void Serialize() 
    {
        // Create a hashtable of values that will eventually be serialized.
        Hashtable addresses = new Hashtable();
        addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052");
        addresses.Add("Fred", "987 Pine Road, Phila., PA 19116");
        addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301");

        // To serialize the hashtable and its key/value pairs,  
        // you must first open a stream for writing. 
        // In this case, use a file stream.
        FileStream fs = new FileStream("DataFile.dat", FileMode.Create);

        // Construct a BinaryFormatter and use it to serialize the data to the stream.
        BinaryFormatter formatter = new BinaryFormatter();
        try 
        {
            formatter.Serialize(fs, addresses);
        }
        catch (SerializationException e) 
        {
            Console.WriteLine("Failed to serialize. Reason: " + e.Message);
            throw;
        }
        finally 
        {
            fs.Close();
        }
    }

   
    static void Deserialize() 
    {
        // Declare the hashtable reference.
        Hashtable addresses  = null;

        // Open the file containing the data that you want to deserialize.
        FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
        try 
        {
            BinaryFormatter formatter = new BinaryFormatter();

            // Deserialize the hashtable from the file and 
            // assign the reference to the local variable.
            addresses = (Hashtable) formatter.Deserialize(fs);
        }
        catch (SerializationException e) 
        {
            Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
            throw;
        }
        finally 
        {
            fs.Close();
        }

        // To prove that the table deserialized correctly, 
        // display the key/value pairs.
        foreach (DictionaryEntry de in addresses) 
        {
            Console.WriteLine("{0} lives at {1}.", de.Key, de.Value);
        }
    }
}
破碎的脸 2014-01-21
  • 打赏
  • 举报
回复
序列化就可以了,但要类支持序列化才行。 http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.85).aspx 可以用System.IO.MemoryStream代替上文中的FileStream
种草德鲁伊 2014-01-21
  • 打赏
  • 举报
回复
http://www.google.com.hk/#newwindow=1&q=binaryformatter&safe=strict
本拉灯 2014-01-21
  • 打赏
  • 举报
回复
你是不是要转成C++的结构体。。。。
shuihan20e 2014-01-21
  • 打赏
  • 举报
回复
引用 6 楼 KarasCanvas 的回复:
[quote=引用 5 楼 shuihan20e 的回复:] 感谢楼上几位,序列化与反序列化解决了,但是有新问题了,接收到的数据多了 直接上代码 接收到的数据多了,还包括程序集的一些内容 ?MTWS.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null MTWS.Net.AppCode.tmsgheadodeSenderRecver
把char[]转换为string,再用BinaryWriter写入流中.[/quote] 不用转成string

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            bw.Write(msghead.MsgCode);
            bw.Write(msghead.Recver);
            bw.Write(msghead.Sender);
            ms.ToArray();
种草德鲁伊 2014-01-21
  • 打赏
  • 举报
回复
引用 5 楼 shuihan20e 的回复:
感谢楼上几位,序列化与反序列化解决了,但是有新问题了,接收到的数据多了 直接上代码 接收到的数据多了,还包括程序集的一些内容 ?MTWS.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null MTWS.Net.AppCode.tmsgheadodeSenderRecver
把char[]转换为string,再用BinaryWriter写入流中.
shuihan20e 2014-01-21
  • 打赏
  • 举报
回复
感谢楼上几位,序列化与反序列化解决了,但是有新问题了,接收到的数据多了 直接上代码

public static byte[] GetBinaryFormatData(object msg)
        {
            byte[] binaryDataResult = null;
            MemoryStream memStream = new MemoryStream();
            IFormatter brFormatter = new BinaryFormatter();
            brFormatter.Serialize(memStream, msg);
            binaryDataResult = memStream.ToArray();
            memStream.Close();
            memStream.Dispose();
            return binaryDataResult;
        }

        public static object RetrieveObject(byte[] binaryData)
        {
            MemoryStream memStream = new MemoryStream(binaryData);
            IFormatter brFormatter = new BinaryFormatter();
            Object obj = brFormatter.Deserialize(memStream);
            return obj;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            tmsghead msghead = new tmsghead();
            
            msghead.MsgCode = textBox1.Text.ToCharArray();
            msghead.Recver = textBox2.Text.ToCharArray();
            msghead.Sender = textBox3.Text.ToCharArray();
            byte[] msg = GetBinaryFormatData(msghead);
            TcpClient client = new TcpClient();
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7860);
            client.Connect(ip);
            if (client.Connected) 
            {

                client.Client.Send(msg, SocketFlags.None);
            }
            
        }
    }
    [Serializable]
    public class tmsghead
    {
        
        public char[] MsgCode;       
        public char[] Sender;
        public char[] Recver;        
        public tmsghead()
        {
            MsgCode = new char[2];
            Sender = new char[6];
            Recver = new char[6];
        }
    }
服务端的测试程序是delphi写的,用的indy组件

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls, Math;

type
  TChar2 = array[0..1] of Char;
  TChar6 = array[0..5] of Char;
  TChar32 = array[0..31] of Char;
  TMsgHead = packed record
    MsgCode: TChar2;
    Sender,
    Recver: TChar6;
  end;

  TMsgBody = packed record
    //msghead: TMsgHead;
    body: TChar32;
  end;

  TForm1 = class(TForm)
    IdTCPServer1: TIdTCPServer;
    Memo1: TMemo;
    Button1: TButton;
    procedure IdTCPServer1Execute(AThread: TIdPeerThread);
    procedure Button1Click(Sender: TObject);
    procedure IdTCPServer1Connect(AThread: TIdPeerThread);
    procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



procedure StrToPChar(var ABuf: array of char; ABufLen: Integer; const AStr: string);
{
  将String转换为PChar,长度不足ABufLen的填充#0
}
var
  Index, LenOfStr: Integer;
begin
  LenOfStr := Length(AStr);
  for Index := 0 to Min(ABufLen, LenOfStr) - 1 do
  begin
    ABuf[Index] := AStr[Index + 1];
  end;
  for Index := LenOfStr to ABufLen - 1 do
  begin
    // 长度不足ABufLen的填充#0
    ABuf[Index] := #0;
  end;
end;

function PCharToStr(ABuf: array of char; ABufLen: Integer): string;
{
  将PChar(#0结尾)转换为string
}
var
  LenOfStr: Integer;
begin
  LenOfStr := Min(ABufLen, StrLen(ABuf));
  if LenOfStr <= 0 then
  begin
    Result := '';
  end
  else
  begin
    SetLength(Result, LenOfStr);
    Move(ABuf[0], Result[1], LenOfStr);
  end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  msghead: TMsgHead;
  msgbody: TMsgBody;
begin
  FillChar(msghead, SizeOf(msghead), 0);
  if AThread.Connection.Connected then begin
    AThread.Connection.ReadBuffer(msghead, SizeOf(TMsgHead));
    Memo1.Lines.Add(PCharToStr(msghead.MsgCode, SizeOf(msghead.MsgCode)));
    Memo1.Lines.Add(PCharToStr(msghead.Sender, SizeOf(msghead.Sender)));
    Memo1.Lines.Add(PCharToStr(msghead.Recver, SizeOf(msghead.Recver)));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  msghead: TMsgHead;
  msgbody: TMsgBody;
begin
  IdTCPServer1.Active := True;
  Memo1.Lines.Add('active');
end;
接收到的数据多了,还包括程序集的一些内容 ?MTWS.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null MTWS.Net.AppCode.tmsgheadodeSenderRecver

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧