C# 中将自定义的structure转换为byte[] 及Stream 和 byte[] 之间的转换(文件流的应用)

来源:互联网 发布:新疆软件行业协会 编辑:程序博客网 时间:2024/05/06 11:21
在Socket编程中经常会碰到将Struct转换为byte数组进行传送的情况. 如果服务器和客户端都是自己开发的话, 用序列化和反序列化当然会比较简单, 但序列化后会数据里会包含一些额外的数据,如:程序集名称、版本、公钥等, 不适用于一端是非托管程序. 在.NET Framework的System.Runtime.InteropServices.Marshal类中包含两个方法可以解决此问题:
StructureToPtr 方法: 将数据从托管对象封送到非托管内存块;
PtrToStructure 方法: 将数据从非托管内存块封送到托管对象。
用以下代码就可以实现struct与byte[]之间的相互转换:
using System.Runtime.InteropServices;

        public static byte[] RawSerialize( object anything )

        {

            int rawsize = Marshal.SizeOf( anything );

            IntPtr buffer = Marshal.AllocHGlobal( rawsize );

            Marshal.StructureToPtr( anything, buffer, false );

            byte[] rawdatas = new byte[ rawsize ];

            Marshal.Copy( buffer, rawdatas, 0, rawsize );

            Marshal.FreeHGlobal( buffer );

            return rawdatas;

        }

 

 

        public static object RawDeserialize( byte[] rawdatas, Type anytype )

        {

            int rawsize = Marshal.SizeOf( anytype );

            if( rawsize > rawdatas.Length )

                return null;

            IntPtr buffer = Marshal.AllocHGlobal( rawsize );

            Marshal.Copy( rawdatas, 0, buffer, rawsize );

            object retobj = Marshal.PtrToStructure( buffer, anytype );

            Marshal.FreeHGlobal( buffer );

            return retobj;

}
例子:

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

            struct YourStruct

        {

            public Int32  First;

            public Int32  Second;

            [MarshalAs( UnmanagedType.ByValTStr, SizeConst=16 )]

            public String Text;

        }

 

        YourStruct st;

        st.First  = 11;

        st.Second = 22;

        st.Text = "Hello";

        byte[] rd = RawSerialize( st );

        // reverse:

        YourStruct rst = (YourStruct) RawDeserialize( rd, typeof(YourStruct));

C# Stream 和 byte[] 之间的转换(文件流的应用)
一. 二进制转换成图片

MemoryStream ms = new MemoryStream(bytes);

ms.Position = 0;

Image img = Image.FromStream(ms);

ms.Close();

this.pictureBox1.Image

二. C#中byte[]与string的转换代码

1、System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
  byte[] inputBytes =converter.GetBytes(inputString);
  string inputString = converter.GetString(inputBytes);

2、string inputString = System.Convert.ToBase64String(inputBytes);
  byte[] inputBytes = System.Convert.FromBase64String(inputString);

FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

三. C# Stream 和 byte[] 之间的转换

/// 将 Stream 转成 byte[]

public byte[] StreamToBytes(Stream stream) 

{

byte[] bytes = new byte[stream.Length]; 

stream.Read(bytes, 0, bytes.Length); 

// 设置当前流的位置为流的开始 

stream.Seek(0, SeekOrigin.Begin); 

return bytes; 

}

/// 将 byte[] 转成 Stream

public Stream BytesToStream(byte[] bytes) 

Stream stream = new MemoryStream(bytes); 

return stream; 

}

四. Stream 和 文件之间的转换

将 Stream 写入文件

public void StreamToFile(Stream stream,string fileName) 

// 把 Stream 转换成 byte[] 

byte[] bytes = new byte[stream.Length]; 

stream.Read(bytes, 0, bytes.Length); 

// 设置当前流的位置为流的开始 

stream.Seek(0, SeekOrigin.Begin); 

// 把 byte[] 写入文件 

FileStream fs = new FileStream(fileName, FileMode.Create); 

BinaryWriter bw = new BinaryWriter(fs); 

bw.Write(bytes);

bw.Close(); 

fs.Close(); 

}

五. 从文件读取 Stream

public Stream FileToStream(string fileName) 

// 打开文件 

FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); 

// 读取文件的 byte[] 

byte[] bytes = new byte[fileStream.Length]; 

fileStream.Read(bytes, 0, bytes.Length); 

fileStream.Close(); 

// 把 byte[] 转换成 Stream 

Stream stream = new MemoryStream(bytes); 

return stream;

}



0 0
原创粉丝点击