【问题标题】:The fastest search algorithm into binary files? [closed]最快的搜索算法到二进制文件? [关闭]
【发布时间】:2012-01-10 10:53:59
【问题描述】:

我正在寻找最快和最好的算法来将一些值搜索到一个非常大的二进制文件(一种 2 GB AFP 文件)中,这意味着将整个数据加载到内存中肯定是不可思议的。我正在使用 C#,我不知道是否有任何其他编程语言 (C/C++..) 会更快,否则我将继续使用 C#。 感谢您的任何想法。

【问题讨论】:

  • "values" 是什么意思?一个字节,一个字节[],一个字符串,什么?
  • 在 64 位 Windows 上加载 2GB 内存是“可以想象的”。
  • 你说你应该搜索字节,但你的目标是什么?数一数你有多少字节?扫描文件直到找到目标字节,以便从那里读取一些 var?请更好地解释您要做什么。
  • 我必须将一些sequents出现在文件中(例如,X'D3A8AF')
  • 这个序列表示一个页面的开始,所以要得到这个文件的页数,我要数一下。

标签: c# algorithm search binary afp


【解决方案1】:

Boyer-Moore 在性能和复杂性之间提供了一个很好的折衷方案(链接的文章有其他方法的链接。

用 C 语言(链接中的源代码)实现将比 C# 快得多,尽管在实践中您可能会发现磁盘 I/O 是最大的障碍。

【讨论】:

    【解决方案2】:

    评论后,我决定提供一个可能的解决方案。
    小心:这个解决方案不是最好的,也不是优雅的。
    以它为起点:

    string SEARCH = @"X'D3A8AF";
    int BUFFER = 1024;
    
    int tot = 0;
    using (FileStream fs = new FileStream(filename, FileMode.Open))
    {
        using (StreamReader sr = new StreamReader(fs))
        {
            char[] buffer = new char[BUFFER];
            int pos = 0;
            while (fs.Position < fs.Length)
            {
                sr.ReadBlock(buffer, 0, BUFFER);
                string s = new string(buffer);
                int i = 0;
                do
                {
                    i = s.IndexOf(SEARCH, i);
                    if (i >= 0) { tot++; i++; }
                }
                while (i >= 0);
                pos += BUFFER;
                if (!s.EndsWith(SEARCH)) pos -= SEARCH.Length;
                fs.Position = pos;
            }
            sr.Close();
        }
        fs.Close();
    }
    

    BUFFER 可以随意修改(增加)。

    【讨论】:

    • @Outifaout:让我知道它是否适合你。
    • 基本上不行,字符串s是二进制格式,无法读取和索引!
    • @Outifaout:为什么?任何char[]都可以转成字符串!
    • char[] 本身带有不可读的字符(类似于@ùøñõò..)
    • 我现在正在做的是以十六进制格式逐字节读取它: int b = file.ReadByte();字符串 s = b.ToString("X");我的问题是我需要一种处理时间的最佳方式!
    【解决方案3】:

    您必须加载整个文件才能搜索对象。如果可能的话,根据唯一 ID 拆分文件(如果有)。就像根据唯一 id 或其他一些参数为每 100 条记录(1-100、101-200、201-300 等)拆分一个文件。这是一种对二进制文件的索引。

    【讨论】:

    • 不,恕我直言,他无法加载整个文件! OP 可以使用 StreamReader 并以块的形式读取文件。这取决于他在寻找什么
    【解决方案4】:

    你可以使用 TextReader.ReadBlock 方法。 逐块读取文件并查找请求的值。 或者甚至更好地使用 BinaryReader.ReadBytes 方法。

    【讨论】:

    • 值表示字节。我正在开发 32 位 Windows。我认为二进制文件不是由使用 StreamReader.ReadLine 的行构成的!
    • 这是一个二进制文件,所以不能有 "lines" IMO。
    • @Outifaout 我已经编辑了帖子并省略了 StreamReader.ReadLine 方法。
    • 块的问题是它有可能错过一些事件。例如,我正在搜索“D3A8AF”,一个块以“D3”结尾,下一个以“A8AF”开头" !
    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 2022-11-25
    • 2012-03-19
    相关资源
    最近更新 更多