如何在二进制文件中查找 ANSI 字符串?

Posted

技术标签:

【中文标题】如何在二进制文件中查找 ANSI 字符串?【英文标题】:How to look for an ANSI string in a binary file? 【发布时间】:2011-09-20 19:51:25 【问题描述】:

我想使用 C++ 查找二进制文件中第一次出现的 ANSI 字符串。

我知道字符串类有一个方便的查找功能,但是如果文件很大,比如 5-10 MB,我不知道如何使用它。

我是否需要先将整个文件复制到内存中的字符串中?如果是,我如何确保复制时不会损坏任何二进制字符?

或者有没有更高效的方法,不需要将其复制到字符串中?

【问题讨论】:

How to delete parts from a binary file in C++ 的可能重复项 你已经问过基本相同的问题 您可以使用内存映射文件。您可以使用 Boost:boost.org/doc/libs/1_46_1/libs/iostreams/doc/classes/…,或 StlSoft:stlsoft.org/doc-1.9/… @GWW:有人告诉我应该把它分成多个问题。 @GWW:其他人在另一个问题上告诉他,他应该将问题分成多个问题,并且在另一个问题上他甚至与这个问题相关。 【参考方案1】:

如果您可以将文件映射到内存中,则可以避免复制。

【讨论】:

【参考方案2】:

首先,不要担心损坏的字符。 (但也不要忘记以二进制模式打开文件!)现在,假设您的搜索字符串是n 字符长。然后,您可以一次搜索整个文件一个块,只要确保保留每个块的最后一个 n-1 字符以添加到下一个块之前。这样您就不会丢失跨越块边界发生的匹配。因此,您可以使用方便的查找功能,而无需一次将整个文件读入内存。

【讨论】:

我认为zsero应该指定目标的长度是否有限制。如果他搜索文本文件的内容作为目标,在另一个文件中搜索该内容,目标本身很容易超过几个块,在这种情况下,这总是会失败。如果他能保证target很小,那么这是一个很好的优化。【参考方案3】:

是否需要先将整个文件复制到内存中的字符串中?

没有。

或者有没有更高效的方法,不需要复制成字符串?

当然;使用std::ifstream 打开文件(确保以binary mode 而不是文本模式打开),在流周围创建一对multi_pass iterators(来自Boost.Spirit),然后搜索字符串std::search.

【讨论】:

好答案!我无法想象更有效的方法。我想提供使用 fstream::read() 函数,然后在读取缓冲区中手动搜索。但我的路比较难。 不错的解决方案。我看到的唯一潜在问题是,这将读取大小等于流缓冲区大小的文件。这个缓冲区大小可以调整吗?一次读取更大的块可能更有效。 @HighCommander4:好问题。通过提供一个单独构造的std::filebuf 实例可能是可能的,但坦率地说,iostreams 不是我的专业领域。 这会调用未定义的行为,因为std::search 需要前向迭代器或更好的迭代器,而std::istream_iterator 是输入迭代器。请参阅我的问题here。 @Benjamin:完全正确,不知道在写这个答案时我是怎么忘记的。 >_>答案已编辑。

以上是关于如何在二进制文件中查找 ANSI 字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在二进制文件C中查找字节

小论字符编码技术

如何在 Erlang 中找到 utf8 编码二进制文件的字符长度?

为啥我的 std::wofstream 写 ansi?

如何在文件中查找子字符串?

如何转换内码