如何解析二进制文件中的文本数据

时间:2015-10-03 00:04:29

标签: c# .net parsing binary

您好我有一个包含大量资源并使用C#的二进制文件我想查找并解析此文件中的文本对象,如下所示

之前的大量二进制垃圾

ONMAP 0 131072"描述" 0"名称" " FLAG" " FLAG" 7900.000000 0.000000 1499.999268 2.000000 6.000000 8.000000 1.000000 1.000000 1.000000 0 0 0 -1 1 0 0 -1 0.101900 2 36 255 然后是换行符

这些对象之后的大量二进制垃圾

每个对象都以其标签ONMAP开头,这些值由空格分隔,字符串双引号,必须按照它们的写入顺序读取,我们不知道数据在文件中的位置所以我想要搜索二进制文件直到找到该onmap并将属性读入List但是一旦发现onmap我就不知道如何解析属性。

2 个答案:

答案 0 :(得分:0)

有一个标准的Unix程序可以完全满足您的需求:strings

您可以在Gnu binutils下找到来源:

http://www.gnu.org/software/binutils/

该程序虽小但相对简单。它使用的“算法”直接适用于C#(或等效地,适用于Java或C ++)。

答案 1 :(得分:0)

我强烈建议通过获取包含指向字符串开头的点的文件格式来定位字符串的开头。以下代码适用于大多数情况,但不能保证。 Gnu实用程序基本上做同样的事情。像这样的公用事业应该只用作快速解决方案。二进制数据是伪随机的,可能有5个字符匹配,但非常遥远。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        enum State
        {
            FIND_ONMAP,
            FIND_RETURN,
            DONE
        }

        const string FILENAME = @"c:\temp\test.txt";
        static void Main(string[] args)
        {
            List<byte> onmap = Encoding.UTF8.GetBytes("ONMAP").ToList();

            FileStream stream = File.OpenRead(FILENAME);
            int data = 0;
            State state = State.FIND_ONMAP;
            List<byte> buffer = new List<byte>();
            while ((data = stream.ReadByte()) != -1)
            {
                switch (state)
                {
                    case State.FIND_ONMAP:
                        if (buffer.Count < 5)
                        {
                            buffer.Add((byte)(data & 0xff));
                        }
                        else
                        {
                            buffer.RemoveAt(0);
                            buffer.Add((byte)(data & 0xff));
                        }
                        if (buffer.SequenceEqual(onmap))
                        {
                            state = State.FIND_RETURN;
                        }
                        break;
                    case State.FIND_RETURN:
                        if (data == 10)
                        {
                            state = State.DONE;
                            break;
                        }
                        else
                        {
                            buffer.Add((byte)(data & 0xff));
                        }
                        break;

                }
                if (state == State.DONE) break;

            }


            if (state == State.DONE)
            {
                string results = Encoding.UTF8.GetString(buffer.ToArray());
                Console.WriteLine(results);
                Console.ReadLine();
            }

        }
    }
}
​