我正在尝试从二进制文件中读取一系列值,但直到运行时我才知道值类型是什么。
简化示例
我有一个 10 字节长的二进制文件。字节依次表示 an int
、 afloat
和 a short
。我在编译时不知道这一点,但在运行时我确实知道这一点,使用这样的数组:
Type[] types = new Type[3];
types[0] = typeof(int);
types[1] = typeof(float);
types[2] = typeof(short);
问题
所以现在我有了这个列表,有没有办法可以使用这些信息快速读取文件中的值?我能想到的唯一方法是使用一个大块if
,但它看起来真的很难看:
for (int i = 0; i < types.Length; i++)
{
if (types[i] == typeof(int))
{
int val = binaryfile.ReadInt32();
//... etc ...
}
else if (types[i] == typeof(float))
{
float val = binaryfile.ReadSingle();
//... etc ...
}
else if //... etc...
}
但这是丑陋和麻烦的。我想知道我是否可以使用数组中的Type
信息types
以某种方式“自动化”这个。
我试过的
我想到的一个想法是将原始字节读入数组,然后对字节数组执行转换。因此,假设我的数组如下所示:
byte[] buf = new byte[10] {
0x40, 0xE2, 0x01, 0x00,
0x79, 0xE9, 0xF6, 0x42,
0x39, 0x30 };
这分别包含int
、float
和short
值 123456、123.456 和 12345。现在我可以执行以下操作:
fixed (byte* bp = &buf[0])
{
int* ip = (int*)bp;
Console.WriteLine("int ptr: {0}", *ip);
}
这似乎运作良好,但有两个问题:
- 我不知道如何编组
*ip
回托管域。 我仍然无法使用我的类型列表,如下:
fixed (byte* bp = &buf[0]) { (types[0])* ip = ((types[0])*)bp; // both errors here Console.WriteLine("int ptr: {0}", *ip); }
这会在指示的行上产生两个编译时错误:
Error 1 Invalid expression term ')'
Error 2 ) expected
这就是我到目前为止所想尝试的。
我希望有人能帮帮忙。我觉得我错过了一些简单的东西,这会让我的生活更轻松。
更新
我已经尝试过 Peter Duniho 的建议,它似乎工作得很好,尽管与大块相比,性能影响很小if
。
以下是来自约 100 MB 文件的一些结果(所有时间都以毫秒为单位):
彼得的方法:
2025
2003
1954
1979
1958
if
堵塞:
1531
1488
1486
1489
没什么太重要的,尽管因为我计划处理大得多的文件(在 GB 范围内),所以这几百毫秒加起来,所以我将坚持使用丑陋的if
块,直到我找到一样快的东西。