c# - 如何在 C# 中的字节数组中查找字节模式?

标签 c# arrays search byte

我正在开发一个项目,我从文件中读取数据,并且需要操作其中一些数据。

数据是二进制的,其中包含一些 ASCII 编码文本。 如果重要的话,数据也会以大尾数法保存。

我想要完成的是找到此数据中的模式并操纵该模式的部分内容。

示例:(09 49 6E 76 65 6E 74 6F 72 79 0A 00 00 00 02 01 00)

这代表数字 9,表示库存中有多少个字母,后面跟着不带引号的 ASCII“库存”。 “0A”标记该 ASCII 文本的结尾,后面跟着 00 00 00 02 标记我们的库存“2”的大小。 “01 00”标志着整个库存区域的结束。

示例2:(04 53 6C 6F 74 00 02 00)

这表示数字 4 表示插槽中有多少个字母,后面跟着不带引号的 ASCII“插槽”。 “00”是 ASCII 文本和槽号“02”之间的空格,后跟区域末尾“00”。

我需要在文件中找到这些模式和其他几个模式。 然后我需要修改部分模式并写入磁盘。

示例修改:(04 53 6C 6F 74 00 02 00)“从上方”更改为(04 53 6C 6F 74 00 07 00),将“插槽号‘02’更改为‘07’。

另一个需要注意的是,虽然我需要在不同大小、长度和包含的数据的文件中搜索多个模式,但这些模式的多个部分可能包含需要单独修改的不同数据,如下所示一个整体。

澄清一下:(库存、槽位、id、计数)- 被视为一个人的信息。

每个被记录的人可以有多个副本(库存、槽位、id、计数)。

我想向用户显示此信息,并为他们提供修改组中每个元素的选项。

我不是一个好的程序员,想学习,如果你有例子我很感激,如果你有建议请给。如果能简化一下就更好了,谢谢。 我现在正在进行一项工作,但现在陷入困境。如果您想看看我有什么,请告诉我。

我所拥有的摘要:将文件读入 byte[],然后将整个数组显示到控制台。就是这样。通过一些格式化和一些调试信息来定位我读入数组的 block 。

这是我在 Pastebin 上的代码的链接。 LINK

我意识到我没有得到所有出现的(库存、槽位、id、计数),我也需要解决这个问题。

编辑:示例 (09 49 6E 76 65 6E 74 6F 72 79 0A 00 00 00 02 01 00) 这是我正在读取的文件中的固定长度的二进制数据 block 。如前所述,09 代表字符串的长度。字符串后面的是 (0A 00 00 00 02 01 00) 其中重要的部分是 (02) 这是因为这是该二进制数据片中唯一发生变化的字节。 “02”代表“2”,表示该特定人员记录有 2 个(槽位、id、计数)实例。

(File)
    (09 Inventory 0A 00 00 00 02 01 00) // Start of person 1's record with 2 instances.
        (Slot)
        (id)
        (Count)
        (Slot)
        (id)
        (Count)
    (Rotation)  // End of person 1's record

    (09 Inventory 0A 00 00 00 04 01 00) // Start of person 2's record with 4 instances.
        (Slot)
        (id)
        (Count)
        (Slot)
        (id)
        (Count)
        (Slot)
        (id)
        (Count)
        (Slot)
        (id)
        (Count)
    (Rotation)  // End of person 2's record
(File End)

我的想法是,我想编辑“id”或通过添加到库存来增加插槽数量,并添加更多(插槽、id、计数)实例。

“id” - 包含项目 ID

“槽位” - 包含库存槽位编号

“计数” - 包含该槽中有多少项目。 编辑注意:如果我不清楚,请告诉我,再次感谢。

最佳答案

你说你不是一个好的程序员。然后我会提出一些基本建议。

首先,对于任何问题,将其分解。尝试将其分解为您可以解决的更简单的子问题,或者认为会更容易解决。您说您想检查文件中的模式,然后可能修改一些数据并将其写回。作为第一步,我想说这些是您需要解决的主要子问题,以便获得完整的解决方案。

  • 读取文件
  • 搜索二进制数据中的模式
  • 进行修改
  • 写出修改后的数据。

您主要关注“搜索模式”部分,因此我将集中对此进行进一步评论。所有其他部分也可能很棘手,但您可以自己解决它们,也可以在 stackoverflow 或其他地方寻找其他人如何解决它们的提示。

好的,现在,关于“搜索模式”。在我阅读你的描述时,

在我看来,字节数组中的第一个字节是文本长度。在 C# 代码中,可以像这样显式声明展示模式的数据数组:

byte[] data = new byte[] { 9, 0x49, 0x6E, 0x76, 0x65, 0x6E, 0x74,
               0x6F, 0x72, 0x79, 0x0A, 0, 0, 0, 2, 1, 0 } ;

当然,您不会显式声明该数组。您将通过文件读取操作创建或填充数组。此时文件读取仍然是一个 Unresolved 问题,但没关系 - 您可以单独解决它。并且,效果是相同的 - 当您成功读取文件时,您将拥有一个类似于上面显式声明的数组的字节数组。

好的,现在你如何操作这些数据?第一个字节是字符串数据的长度。接下来的 N 个字节是字符串数据。然后你还有一些其他的东西。

您没有准确描述您想要进行哪些“修改”,但根据您提供的信息,应该很容易浏览数据。

如果你想获取数组中数据的“切片”,你可以这样做。

int length = (int) data[0];
byte[] s = new byte[length];
Array.Copy(data, 0, s, 0, length);
// now, s contains N bytes, representing the string

您可能想做的下一件事是从您切出的字节中获取实际的字符串。为此,请使用 the Encoding class :

String word = System.Text.Encoding.UTF8.GetString(s);

我不明白字符串数据后面的数据的模式。在某些情况下,它是 00,在某些情况下,它是 0A

但也许您知道其中的模式。按照同样的方法,您可以遍历一条“记录”的所有数据。当您到达记录末尾时,然后重新开始并处理下一条记录。获取下一个“记录”的关键是知道要从文件中读取的数据中取出多大的数据片段。


这让我们回到“读取文件”子问题。从文件中获取适量数据的一种方法是仅读取第一个字节,然后再读取文件中的 N 个字节。 (参见System.IO.Stream.Read)。

byte[] size = new byte[1];
var fileStream = File.OpenRead(path);
int offset = 0;
int n;
n = fileStream.Read(size, offset, 1);
// size[0] now contains the byte of data indicating the number of bytes to follow

此时可以读取接下来的N个字节:

int length = (int)size[0];
byte[] stringData = new byte[length];
n = fileStream.Read(stringData, offset, length);

现在你可以获取字符串了。

String word = System.Text.Encoding.UTF8.GetString(stringData);

...等等。读取所有尾随字节。此时,fileStream 隐式保存的游标指向文件中的下一条记录。

关于c# - 如何在 C# 中的字节数组中查找字节模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11378691/

相关文章:

javascript - 删除多维数组中的某些值

c# - 从 DataGridView 中检索选定的行(类)作为对象类(无法转换对象)

c# - 使用 ManualResetEventSlim 而不是 ManualResetEvent 的最短等待时间是多少?

python - 将包含字符串和int对象的列表转换为字节数组以进行套接字通信

java - 初始化二维对象数组时出现空指针异常[Java]

php array_search 0 索引

PHP 搜索表中的不同字段并显示各自的结果

mysql - 在 mysql : table with one column or many smaller columns 中更快的搜索是什么

c# - 我可以通过 OAuth 2.0 使用 Chrome 网上应用店付款吗

c# - 使用 LINQ 从 2 个集合中检索非重复项