【问题标题】:Parsing a binary file with multiple data types into an array将具有多种数据类型的二进制文件解析为数组
【发布时间】:2016-02-13 18:42:24
【问题描述】:

我创建了多个二进制文件,每个文件包含 2 个字符串、2 个字符、1 个双精度和 1 个整数。读取的数据是

Fokker DR 1 
Germany 
D 
A 
1000.0 
13

而二进制文件内容如下:

我正在尝试将 dat 文件解析为一个数组,以便我可以用适当的名称标记每个数据类型,例如

Name: Fokker DR 1
Country: Germany
Attack Mode: D
Turn Mode: A
etc.

但是我遇到了麻烦,因为在尝试使用 StreamReader 并在每个空格实例处拆分二进制文件时,由于名称(Fokker DR 1)包含多个不应包含的空格,我遇到了问题分裂。

这是我尝试拆分的代码:

if (file.Contains("plane1"))
{
    StreamReader reader = new StreamReader("plane1.dat");
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        string[] data = line.Split(' ');
        bin.ReadBinary("plane1.dat");
        Console.WriteLine("Name: " + data[0]);
        Console.WriteLine("Country: " + data[1]);
        Console.WriteLine("Turn Mode: " + data[2]);
        Console.WriteLine("Attack Mode: " + data[3]);
        Console.WriteLine("Cost: " + data[4]);
        Console.WriteLine("Max Damage: " + data[5]);
    }
}

是否有任何方法可以对不同数据类型的每个实例进行拆分,或者是否有另一种方法可以在我的二进制文件中标记数据?

【问题讨论】:

  • 了解序列化并使用其中之一,如XmlSerializerBinaryFormatterSoapFormatterJavascriptSerializerDataContractSerializerDataContractJsonSerializer 等......自定义序列化器/反序列化器应该处理许多极端情况...
  • 看起来这两个字符串由 ASCII 制表符 (0x07) 分隔。之后,您需要了解有关数据的更多信息,例如整数是四个字节,双精度是八个字节,两个字符之间填充。

标签: c# arrays split binary


【解决方案1】:

BinaryFormatter 不会处理该文件格式。鉴于小尺寸和简单的规格,一些自定义读取逻辑应该可以解决问题。

如果您使用BinaryReader 打开文件,您可以自行决定如何处理您将要读取的下一个或多个字节。如果文件的格式不复杂,这很容易做到。根据您的规格,我创建了此代码来读取您的文件:

using(var br = new BinaryReader(
    File.Open(@"c:\tmp\plane.dat", FileMode.Open),
    Encoding.ASCII))
{
    while(br.BaseStream.Position < br.BaseStream.Length)
    {
        var name = br.ReadString();
        var country = br.ReadString();
        var turnmode = br.ReadChar();
        var attackmode = br.ReadChar();
        var cost = br.ReadDouble();
        var maxdamage = br.ReadInt32();

        // you can use above vars what ever you need to do 
        // with them, writing to the console or adding to 
        // a list for example
        // Planes.Add(new Plane {Name = name});
    }
}

在我的测试中,我创建的文件与您的二进制格式匹配。由于您没有显示下一条记录的开始位置,您可能会发现需要进行额外读取,例如使用 ReadByte,但这取决于您的实际结构。

【讨论】:

  • 在我的名为 ReadBinary() 的方法中,我读取了每个单独的数据类型,我刚刚“作弊”并写入字符串 strData2 = input.ReadString(); Console.WriteLine("国家:"+ strData2);我说作弊是因为我不认为那是我的本意,但它完成了工作。谢谢您的回答。事后我尝试实施你的方式,它也有效。
猜你喜欢
  • 1970-01-01
  • 2013-09-30
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 2022-11-28
相关资源
最近更新 更多