用Silverlight如何读取二进制数据结构

ShiningstarHu 2011-08-31 03:49:28

最近开发遇到问题:在Silverlight中获得一个二进制Stream,是一个结构化的文档,先需要把文件内容读取出来。
在Winform中可以我是用了如下方法读、写该文件的。


public static T ReadStruct<T>(Stream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
stream.Read(buffer, 0, Marshal.SizeOf(typeof(T)));
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
T typedStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return typedStruct;
}

public static void WriteStruct<T>(T inputStruct, Stream stream) where T: struct
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
//Allocate the buffer to memory and pin it so that GC cannot use the space (Disable GC)
Marshal.StructureToPtr(inputStruct, handle.AddrOfPinnedObject(), false);
// copy the struct into int byte[] mem alloc
handle.Free(); //Allow GC to do its job
stream.Write(buffer, 0, buffer.Length);
}


由于Marshal.SizeOf, GCHandle.Alloc, Marshal.StructureToPtr以及 GCHandle.Free等方法在Silverlight中是被标记为
[SECURITY CRITICAL]的方法,因此无法直接使用。 网上查了半天没找到很好的解决方法。 现求助CSDN的大侠们。
...全文
132 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
allenhiman 2011-08-31
  • 打赏
  • 举报
回复
哦 能转成SL的代码当然好了。。。
ShiningstarHu 2011-08-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 allenhiman 的回复:]

不知道你是在什么环境下用到的SL插件。

有一种解决办法 就是利用MFC,ATL等写一个ActiveX插件。 然后在插件中处理你所说的二进制处理。
通过网页和SL的通信 以及 网页和ActiveX的通信 进而融汇贯通 当然说起来容易,全部实现了也要费不少力气。
[/Quote]

我写了一个Silverlight分割ASF(WMV) 文件的功能。 由于原来是用Winform的,变态的老板希望要在Silverlight上实现。

你所说的方法太复杂了,而且不能保证跨平台,ActiveX在非Windows平台下无法运行。

发了贴就你一个人回答,虽然也没多少解决我的问题,不过本人还是很慷慨的。100分就是你的了。哈哈哈。。。
ShiningstarHu 2011-08-31
  • 打赏
  • 举报
回复
自己已经搞定了。5、6年没来CSDN了,和原来的CSDN比起来现在解决问题的速度差了点。
造福遇到此问题的人们。

要解决这个问题,简单的讲就是要避免使用Marshal.SizeOf和Marshal.StructureToPtr等2个方法,并且把文件按照二进制结构读取出来。

给个简化的版本,上面的ReadStruct修改成如下即可

public static T ReadStruct<T>(Stream stream) where T : class, new()
{
var strct = new T();
var fi = strct.GetType().GetFields();
var readCount = 0;
foreach (var info in fi)
{
var t = info.FieldType;

if (t == typeof(byte))
{
readCount = 1;
var buffer = new byte[readCount];
stream.Read(buffer, 0, readCount);
info.SetValue(strct, buffer[0]);
}
//elseif (其他类型).....
}
}
allenhiman 2011-08-31
  • 打赏
  • 举报
回复
不知道你是在什么环境下用到的SL插件。

有一种解决办法 就是利用MFC,ATL等写一个ActiveX插件。 然后在插件中处理你所说的二进制处理。
通过网页和SL的通信 以及 网页和ActiveX的通信 进而融汇贯通 当然说起来容易,全部实现了也要费不少力气。

8,737

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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