查询序列化对象文件

时间:2012-01-13 10:58:35

标签: c# .net linq

无论如何都没有将整个文件加载到内存中吗?如果是这样,你建议我做什么?

班级实施:

[Serializable()]
public class Car
{
    public string Brand { get; set; }
    public string Model { get; set; }
}

[Serializable()]
public class CarCollection : List<Car>
{
}

序列化到文件:

CarCollection cars = new CarCollection
{
    new Cars{ Brand = "BMW", Model = "7.20" },
    new Cars{ Brand = "Mercedes", Model = "CLK" }
};

using (Stream stream = File.Open("data", FileMode.Create))
{
    BinaryFormatter bin = new BinaryFormatter();
    bin.Serialize(stream, cars);
}

3 个答案:

答案 0 :(得分:2)

如果序列化为XML,则可以使用SAX解析器(XmlReader class),它将从流中读取数据。

答案 1 :(得分:1)

要一次反序列化一个对象,您还需要一次序列化一个对象。

最简单的方法是定义自己的泛型类:

public static class StreamSerializer
{
    public static void Serialize<T>(IList<T> list, string filename)
    {
        using (Stream stream = File.Open(filename, FileMode.Create))
        {
            BinaryFormatter bin = new BinaryFormatter();

            // seralize each object separately
            foreach (var item in list)
                bin.Serialize(stream, item);
        }
    }

    public static IEnumerable<T> Deserialize<T>(string filename)
    {
        using (Stream stream = File.Open(filename, FileMode.Open))
        {
            BinaryFormatter bin = new BinaryFormatter();

            // deserialize each object separately, and 
            // return them one at a time

            while (stream.Position < stream.Length)
                yield return (T)bin.Deserialize(stream);
        }
    }
}

然后你可以简单地写:

CarsCollection cars = new CarsCollection
{
    new Cars{ Brand = "BMW", Model = "7.20" },
    new Cars{ Brand = "Mercedes", Model = "CLK" }
};

// note that you cannot serialize the entire list if
// you want to query without loading - it must be symmetrical

StreamSerializer.Serialize(cars, "data.bin");

// the following expression iterates through objects, processing one 
// at a time. "First" method is a good example because it
// breaks early.

var bmw = StreamSerializer
    .Deserialize<Cars>("data.bin")
    .First(c => c.Brand == "BMW");

如果您的CarsCollection属于不同的类,则可能会出现稍微复杂的情况。在这种情况下,您需要实现ISerializable,但原则类似。

在旁注中,通常的惯例不是将实体命名为复数(即Cars应命名为Car)。

答案 2 :(得分:0)

通常你可以使用某种类型的阅读器(StreamReader,BinaryReader,...)和BufferedStream。