C# 最快的二进制文件搜索算法?

C# 最快的二进制文件搜索算法?,c#,algorithm,search,binary,afp,C#,Algorithm,Search,Binary,Afp,我正在寻找最快和最好的算法,将一些值搜索到一个非常大的二进制文件(类似于2GB的AFP文件),这意味着将整个数据加载到内存中肯定是不可想象的。我正在使用C#,我不知道是否有其他编程语言(C/C++…)会更快,否则我将继续使用C#。 谢谢您的建议。您必须加载整个文件才能搜索对象。如果可能,根据唯一id(如果有)拆分文件。例如,根据唯一id或某些其他参数,为每100条记录(1-100、101-200、201-300等)拆分一个文件。这是一种对二进制文件的索引。您必须加载整个文件才能搜索对象。如果可能

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

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

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

您可以使用TextReader。方法。 逐块读取文件并查找请求的值。 或者更好地使用BinaryReader。方法。

您可以使用TextReader。方法。 逐块读取文件并查找请求的值。
或者更好地使用BinaryReader。方法。

在评论之后,我决定提供一个可能的解决方案。
小心:此解决方案既不是最好的,也不是优雅的。
将其作为起点:

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();
}
string SEARCH=@“X'D3A8AF”;
int缓冲区=1024;
int-tot=0;
使用(FileStream fs=newfilestream(filename,FileMode.Open))
{
使用(StreamReader sr=新StreamReader(fs))
{
char[]buffer=新字符[buffer];
int pos=0;
而(fs.位置=0){tot++;i++;}
}
而(i>=0);
pos+=缓冲区;
如果(!s.EndsWith(SEARCH))pos-=SEARCH.Length;
fs.位置=位置;
}
高级关闭();
}
fs.Close();
}

缓冲区
可以根据您的要求进行修改(增加)。

在评论之后,我决定提供一个可能的解决方案。
小心:此解决方案既不是最好的,也不是优雅的。
将其作为起点:

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();
}
string SEARCH=@“X'D3A8AF”;
int缓冲区=1024;
int-tot=0;
使用(FileStream fs=newfilestream(filename,FileMode.Open))
{
使用(StreamReader sr=新StreamReader(fs))
{
char[]buffer=新字符[buffer];
int pos=0;
而(fs.位置=0){tot++;i++;}
}
而(i>=0);
pos+=缓冲区;
如果(!s.EndsWith(SEARCH))pos-=SEARCH.Length;
fs.位置=位置;
}
高级关闭();
}
fs.Close();
}
缓冲区
可以随意修改(增加)。

在性能和复杂性之间提供了一个很好的折衷方案(链接的文章中有指向其他方法的链接)

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

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



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

用“值”是什么意思?一个字节,一个字节[],一个字符串,什么?在64位Windows上,在内存中加载2GB是“可以想象的”。你说你应该搜索字节,但你的目标是什么?数一数你有多少字节?扫描文件直到找到一个目标字节,这样你就可以从中读取一些变量了?请更好地解释你想做什么。我必须在文件中计算一些连续发生的事件(例如,X'D3A8AF')这个序列表示一个页面的开始,所以要得到这个文件的页数,我必须计算它。你说的“值”是什么意思?一个字节,一个字节[],一个字符串,什么?在64位Windows上,在内存中加载2GB是“可以想象的”。你说你应该搜索字节,但你的目标是什么?数一数你有多少字节?扫描文件直到找到一个目标字节,这样你就可以从中读取一些变量了?请更好地解释你想做什么。我必须在文件中计算一些连续发生的事件(例如,X'D3A8AF')这个序列表示一个页面的开始,所以要得到这个文件的页数,我必须数一数。不,他不能加载整个文件IMHO!!OP可以使用StreamReader并分块读取文件。这取决于他搜索的内容不,他不能加载整个文件IMHO!!OP可以使用StreamReader并分块读取文件。这取决于he搜索的值是字节数。我在32位windows上工作。我认为二进制文件的结构不适合使用StreamReader.ReadLine!它是一个二进制文件,所以不能有“行”IMO.@Outifaout我编辑了这篇文章并省略了StreamReader.ReadLine方法。块的问题是它有可能错过一些事件。例如,我正在搜索“D3A8AF”,一个块以“D3”结尾,下一个块以“A8AF”开头!值表示字节。我正在32位windows上工作。我认为二进制文件的结构不是按行来使用StreamReader.ReadLine!它是一个二进制文件,因此不能有“行”依我看,@Outifaout我编辑了这篇文章,省略了StreamReader.ReadLine方法。块的问题是它有可能错过一些事件。例如,我正在搜索“D3A8AF”,一个块以“D3”结尾,下一个块以“A8AF”开头!@Outifaout:让我知道它是否适合你。基本上它不适合你