C# 在不将数据放入内存的情况下使用LINQ

C# 在不将数据放入内存的情况下使用LINQ,c#,linq,file,C#,Linq,File,我在一个二进制文件中有大量的数据记录,我想在其中搜索一些东西。是否有任何方法可以在文件数据上使用LINQ语句,而不将所有数据放入内存中(如List) 我有使用列表的方法: 私人书籍阅读(多头) { 书籍; 使用(Stream st=File.Open(HttpContext.Current.Server.MapPath(“/”)+“library.majid”、FileMode.OpenOrCreate、FileAccess.Read)) { st.位置=位置; 使用(BinaryReader=

我在一个二进制文件中有大量的数据记录,我想在其中搜索一些东西。是否有任何方法可以在文件数据上使用LINQ语句,而不将所有数据放入内存中(如
List

我有使用
列表的方法

私人书籍阅读(多头)
{
书籍;
使用(Stream st=File.Open(HttpContext.Current.Server.MapPath(“/”)+“library.majid”、FileMode.OpenOrCreate、FileAccess.Read))
{
st.位置=位置;
使用(BinaryReader=新的BinaryReader(st))
{
如果(!reader.ReadBoolean())
返回null;
书=新书
{
Id=reader.ReadInt32(),
Name=reader.ReadString(),
Dewey=reader.ReadString()
};
尝试
{
book.Subject=reader.ReadString();
book.RegDate=reader.ReadInt32();
book.PubDate=reader.ReadInt32();
}
catch(EndOfStreamException){}
}
}
还书;
}
私有列表getAll(int-recordLength=100)//按Id排序的结果!!
{
龙伦;
使用(Stream st=File.Open(HttpContext.Current.Server.MapPath(“/”)+“library.majid”、FileMode.OpenOrCreate、FileAccess.Read))
{
Len=标准长度;
}
List res=新列表();
Book ReadedBook=null;
对于(int i=0;ix.Id.CompareTo(y.Id));
返回res;
}

如果是文本文件,则可以使用
file.ReadLines(filename)
返回
IEnumerable
,而无需将文件加载到内存中

ReadLines和ReadAllLines方法的区别如下:使用ReadLines时,可以在返回整个集合之前开始枚举字符串集合;使用ReadAllLines时,必须等待返回整个字符串数组,然后才能访问该数组。因此,当您处理非常大的文件时,ReadLines会更加高效

例如:

var count = File.ReadLines(somefile)
                .Where(line => line.StartsWith("something"))
                .Count();
编辑


如果是二进制文件呢

然后您可以编写类似于以下内容的方法:

public static IEnumerable<Book> ReadBooks(string filename)
{
    using (var f = File.Open(filename, FileMode.Open))
    {
        using (BinaryReader rdr = new BinaryReader(f))
        {
            Book b = new Book();
            //.....
            yield return b;
        }
    }
}
publicstaticIEnumerableadbooks(字符串文件名)
{
使用(var f=File.Open(filename,FileMode.Open))
{
使用(BinaryReader rdr=新的BinaryReader(f))
{
书b=新书();
//.....
收益率b;
}
}
}

如果是文本文件,则可以使用
file.ReadLines(filename)
返回
IEnumerable
,而无需将文件加载到内存中

ReadLines和ReadAllLines方法的区别如下:使用ReadLines时,可以在返回整个集合之前开始枚举字符串集合;使用ReadAllLines时,必须等待返回整个字符串数组,然后才能访问该数组。因此,当您处理非常大的文件时,ReadLines会更加高效

例如:

var count = File.ReadLines(somefile)
                .Where(line => line.StartsWith("something"))
                .Count();
编辑


如果是二进制文件呢

然后您可以编写类似于以下内容的方法:

public static IEnumerable<Book> ReadBooks(string filename)
{
    using (var f = File.Open(filename, FileMode.Open))
    {
        using (BinaryReader rdr = new BinaryReader(f))
        {
            Book b = new Book();
            //.....
            yield return b;
        }
    }
}
publicstaticIEnumerableadbooks(字符串文件名)
{
使用(var f=File.Open(filename,FileMode.Open))
{
使用(BinaryReader rdr=新的BinaryReader(f))
{
书b=新书();
//.....
收益率b;
}
}
}

如果您只想搜索某些数据,可以保留方法的类似实现
getAll
,传递一些参数以执行搜索并返回列表(或
IEnumerable
)。这样,您只在内存中保留结果项

您的
Read
方法不会将元素保留在内存中(仅在方法范围内)


顺便说一下,您可以将流读取器传递给
Read
方法,这样您就不会为每次迭代创建新读取器。流“游标”将保留最后一块读取数据的位置。

如果您只想搜索某些数据,可以保留方法的类似实现
getAll
,传递一些参数以执行搜索并返回列表(或
IEnumerable
)。这样,您只在内存中保留结果项

您的
Read
方法不会将元素保留在内存中(仅在方法范围内)


顺便说一下,您可以将流读取器传递给
Read
方法,这样您就不会为每次迭代创建新读取器。流“游标”将保留最后一块读取数据的位置。

考虑显示您的文件结构和一些显示您当前工作的代码。不将数据放入内存有什么好处?如果对象不在内存中,您无法使用linq to对象。您可以编写一个自定义查询提供程序。@Brad如果系统内存小,系统将slow@majidgeek我建议您搜索<代码>二进制序列化< /C>。考虑显示您的文件结构和一些显示当前工作的代码。没有将数据存储到内存中的优点是什么?没有它们,就不能使用LINQ到对象。在记忆中。您可以编写一个自定义查询提供程序。@Brad如果系统内存小,系统将slow@majidgeek我建议您搜索
二进制序列化
。如果它是二进制文件呢?@majidgeek类似于您的代码。从二进制文件(ReadInt32、ReadString等)中读取并分配
书籍的属性。只需在
/../..
处分配属性即可。如果它是二进制文件呢?@majidgeek就像你的代码一样。从二进制文件(ReadInt32、ReadString等)读取并分配属性