C# 在表示字符串的大字节数组中寻找子数组
Posted
技术标签:
【中文标题】C# 在表示字符串的大字节数组中寻找子数组【英文标题】:C# looking for subarrays in large byte array representing strings 【发布时间】:2021-12-22 05:13:37 【问题描述】:在我的应用程序中,我需要打开一个文件,查找一个标签,然后根据该标签执行一些操作。
但!文件内容将每个char
与/0
交替,因此文本“CODE”变为0x43 0x00 0x4F 0x00 0x44 0x00 0x45 0x00
(以十六进制字节表示)。
问题在于终结符也是 /0
,因此带有终结符的“CODE123”看起来像这样:
0x43 0x00 0x4F 0x00 0x44 0x00 0x45 0x00 0x31 0x00 0x32 0x00 0x33 0x00 0x00 0x00
由于/0
是空字符串终止符,如果我使用File.ReadAllText()
我只会得到垃圾,
所以我尝试使用File.ReadAllBytes()
,然后清除每个字节等于0
。
这让我获得了可读的文本,但随后我丢失了有关数据何时结束的信息,即如果文件中有 CODE123[terminator]PROP456[terminator]blablabla
我最终得到 CODE123PROP456blablabla。
所以我决定将文件内容作为byte[]
获取,然后寻找另一个byte[]
用CODE-with-/0-inside 数据初始化。这理论上应该可行,但由于数据数组相当大(大约 150 万个元素),这需要的时间太长了。
蛋糕上的最后一颗樱桃是我正在寻找多次出现的 CODE 标签,所以我不能一找到就停下来。
我尝试修改此处作为答案发布的 LINQ:Find the first occurrence/starting index of the sub-array in C# 如下:
var indices = (from i in Enumerable.Range(0, 1 + x.Length - y.Length)
where x.Skip(i).Take(y.Length).SequenceEqual(y)
select (int?)i).ToList();
但是,一旦我尝试枚举结果,它就会陷入困境。
所以,我的问题是:我怎样才能有效地在一个大数组中找到多个子数组?谢谢
【问题讨论】:
在其他地方查看我的答案,其中解释了如何实现 Boyer-Moore 搜索二进制数据:***.com/a/37500883/106159 空值似乎不是空字符串终止符。您只需要使用正确的编码读取它,它们只是该编码字符的一部分。大概是某种 utf16,但您应该比我们更了解您的文件编码是什么。 ReadAllText 对编码有重载。 @Ralf 这正是问题所在:它们不是终止符,除非它们被用作一个,所以如果我尝试解释它们,我会得到垃圾(第一个被视为空字符串终止符,基本上破坏整个字符串解释),无论我尝试什么编码。 如果您使用 ReadAllText 和 Encoding.Unicode 阅读,您会得到一个带有字符串终止符的字符串来分隔各个子字符串。然后 Split 会给你一个单独的字符串数组。 我不太相信 ;) 您是否尝试过更改字节顺序的编码,例如 BigEndianUnicode?span> 【参考方案1】:The wonderful Boyer-Moore algoryth suggested by Matthew Wilson 惊人地解决了我的问题。
然后我必须找到一个解决方案来查找实际的字符串终止,这看起来太特定于应用程序而对其他人有用,所以我没有发布它。如果您认为它可能有用,请告诉我,我会在这里发布:)
【讨论】:
以上是关于C# 在表示字符串的大字节数组中寻找子数组的主要内容,如果未能解决你的问题,请参考以下文章