请教 C# 中一个基本的数据处理问题

xade 2004-08-29 06:44:41
我用 byte[] 以 FileStream 读入了一个文件,现在我想以 uint[] 用数组的方式处理其中的数据,如果是在 c++ 中,我可以这么做:

//以 BYTE 数组对应到 C# 的 byte[]
...
BYTE data[xxx];
fread(data, ...);
LPDWORD ptr = (LPDWORD)data;
...
//以 ptr[i] 的形式对数据进行处理
...


在 C# 中,我暂时找到两种方法:
1. 使用 Buffer.BlockCopy(...) 将 byte[] 的数据 copy 到一个 uint[] 中。
这么做的话无疑增加了空间上的开销,当 byte[] 的长度很大的时候这是相当不划算的。

2. 使用 unsafe + fixed 以指针的方式进行处理。
这么做在空间和效率上都能得到保证,但是在一个数据处理为主的程序中这么做的话我觉得还不如直接换成用 C++ 算了,一来在 C# 中使用指针一来比 C++ 麻烦,二来牺牲了安全性和 C# 的 GC 机制带来的便利,实在有些舍本逐末的嫌疑。


遇到这个问题的时候我翻了很久的 msdn、csdn 和 google,但是都找不到似乎更好的解决方式。
我用 C++ 勉强还可以算是熟练,但是学 C# 还算久,做数据处理的时候没了指针就跟浑身被绑住了一样,难受得很-_____________-(我平时涉及得比较多的主要是二进制数据的处理)

希望各位指点一下,就这个具体的问题上,可有更好的办法吗?
再具体来说,我想知道是否存在能够暂时将 byte[] 中的数据当作 uint[] 来处理?
能否在不要求更多的存储空间的情况下完成这种转换?

ps. 我也想过使用 BinaryReader 来把数据处理成 uint 数组,但是 BinaryReader 一次只能读取一个 uint,我认为一次性将文件全部加载到内存然后再处理更有效率。而且就我遇到的情况,整个读入的文件不仅需要被作为 uint[] 处理,稍后还需要被当作一般的 byte[] 以逐字节的方式进行处理,而且两种形式的处理是会交叉的,对于 C/C++ 来说,使用指针和强制类型转换很轻松就可以解决这个问题,但是在 C# 里就着实让我头痛了,难道 C# 不适合用来处理二进制数据吗?(在我看来 C++ 在这方面是强项的,而且有 stl 做强大的后盾。而就我目前的 C# 经验,这就给我这样的感觉,希望是我错了-___-b)请各位有经验的高手指点一下,介绍些经验吧m(_ _)m
...全文
239 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xade 2004-09-08
  • 打赏
  • 举报
回复
多谢楼上,看来我还是用 unsafe 算了:)
qqchen79 2004-09-06
  • 打赏
  • 举报
回复
>> 难道是标题没有吸引力众高手对这种问题不屑吗

讨论的人不多是因为这个问题触到了C#的软肋。我想不出一个不使用unsafe指针并且和C++同样有效的方法——即使是BinaryReader,也比C++的方法要多一次内存拷贝。说到底就是安全性和性能的取舍问题:如果这段代码对程序性能的影响不大,那么FileStream或者MemoryStream加上BinaryReader要干净清楚安全的多,如果它对程序的总体性能至关重要,那么使用fixed/unsafe/pointer也是完全合理的解决方法——毕竟C#提供了这些语法构件。
xade 2004-09-04
  • 打赏
  • 举报
回复

难道是标题没有吸引力众高手对这种问题不屑吗
可怜地 up...
csq0516 2004-09-03
  • 打赏
  • 举报
回复
up
xade 2004-09-02
  • 打赏
  • 举报
回复
up
qimini 2004-09-01
  • 打赏
  • 举报
回复
这个我就不知道了
xade 2004-09-01
  • 打赏
  • 举报
回复
不是指单纯的数据类型转换,而是把 4 个 byte 当成一个 uint 操作,在 C++ 中是像这样的:

...
LPBYTE lpubData = new BYTE[xxx];
LPDWORD lpdwData = (LPDWORD)lpubData;

// 现在对 lpdwData[0] 的操作就将会同时影响到 lpubData[0]、lpubData[1]、lpubData[2] 和 lpubData[3] 这 4 个字节里的内容

我想知道除了用指针之外还有什么方法可以实现这样的操作。
qimini 2004-08-31
  • 打赏
  • 举报
回复
byte[] x = new byte[]{1,2,3,33,50,80,70,155,210,5,239};
uint i = x[0];//在C#里byte向unit的装换是隐式完成的,你可以把一个byte直接当成unit类型的变量来处理而不会产生异常或者溢出
liujuanwh 2004-08-31
  • 打赏
  • 举报
回复
up
xade 2004-08-31
  • 打赏
  • 举报
回复
up...
khpcg 2004-08-31
  • 打赏
  • 举报
回复
parse或convertTo行吗?
xade 2004-08-29
  • 打赏
  • 举报
回复
啊啊是学 C# 还不算久...

打掉个字不好意思 *^^*

111,095

社区成员

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

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

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