【问题标题】:Searching for strings in big binary files在大型二进制文件中搜索字符串
【发布时间】:2009-08-18 13:08:46
【问题描述】:

我有一个大的二进制文件(1 MB

编辑:索引文件中的字符串按排序顺序排列。

【问题讨论】:

  • 我也遇到过类似的情况。使用传统的字符串搜索逐个字符读取(假设为 ASCII)。由于您已经有一个索引文件,我认为您无法进一步提高性能。

标签: c# .net file-io


【解决方案1】:

【讨论】:

  • 不幸的是,Boyer-Moore 似乎不值得在 C# 中实现。查看blackbeltcoder.com/Articles/algorithms/…
  • @Jonathan Wood:如果您可以将整个文件加载到内存中并使用IndexOf,则不会。但是对于流式数据,.NET 不提供搜索方式,在这种情况下推荐使用 Boyer-Moore 算法。
  • @Groo:听起来很有趣。想为Black Belt Coder 写另一篇文章吗? :-)
【解决方案2】:

按排序顺序(按字符串)存储 {string, size, offset} 元组,并对字符串使用二进制搜索。

您还可以在文件的开头存储字符串的每个首字母的偏移量。例如,如果以 'a' 开头的字符串从位置 120 开始,而以 'b' 开头的字符串在文件中的位置 2000 开始,您可以使用类似 120, 2000, ...

【讨论】:

    【解决方案3】:

    如果编码是固定的(ASCII),则相对简单。打开一个二进制流,逐字节读取并匹配目标字符串的第一个字符。

    如果您有使用另一种 (UTF-8) 编码的字符串,它会变得更加棘手。

    【讨论】:

      【解决方案4】:

      首先,在文件上使用内存映射。这将比将其读入 RAM 效率更高,因为只有一个副本而不是两个副本(一个在您的程序中,一个在文件缓存中)。

      如果每个字符串都是固定长度的,那么二分查找就非常容易,因为您可以将内存视为字符数组的数组。

      如果每个字符串都是可变长度但以 0 结尾,那么您可以使用二进制搜索的变体,跳到字符串列表的中间,搜索下一个 0,然后测试下一个字符串。然后向前或向后跳到字符串列表的 1/4 或 3/4 并重复。

      如果每个字符串在 Pascal 样式中都是可变长度的,并且在开头有一个字节数,那就更棘手了。对于不频繁的搜索,从一开始的线性搜索不会太慢。如果您正在寻找完全匹配的字符串,请不要忘记您可以通过检查长度是否不匹配来跳过大多数字符串。

      如果您必须经常搜索列表,那么构建一个指向字符串列表的 char 指针数组将再次使二进制搜索变得非常容易。如果这个文件真的是一个用于快速搜索的索引文件,那么它可能已经在某个地方有这个,除非设计者打算在加载文件时构建一个 char 指针数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-23
        • 2020-09-27
        • 2021-11-19
        • 2022-07-31
        • 1970-01-01
        • 2015-05-17
        • 2021-04-15
        相关资源
        最近更新 更多