2012-01-13 45 views
1

有没有办法在不将整个文件加载到内存的情况下实现该目标?如果是这样,你建议我做什么?查询序列化的目标文件

类实现:

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

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

序列化到文件:

+0

它是否序列化为XML? – Groo 2012-01-13 11:00:54

+0

@Groo nope,它没有被序列化为XML。我已经将类实现添加到了我的问题中。 – onatm 2012-01-13 13:19:05

+0

序列化并不实际将二进制文件加载到内存中,它会通过流并在运行中对其进行反序列化。但是在完成之后,整个对象被加载到内存中,这使我认为你只想加载它的一部分。那会是哪一部分?单一财产?当你说“查询”时,你是指LINQ查询?因为在这种情况下应该有一个对象的集合,这在您的代码中是不可见的。 – Groo 2012-01-13 13:33:30

回答

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属于不同类

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"); 

稍微更复杂的情况可能。在这种情况下,您需要实施ISerializable,但原理相似。

在附注中,通常的约定不是以复数命名实体(即Cars应该命名为Car)。

2

如果序列化成XML,你可以使用SAX解析器(XmlReader class),它将从流seqentially读取。

+0

我不喜欢序列化为XML。如果我选择JSON序列化怎么办? – onatm 2012-01-13 13:29:06

+0

@onatm:是的,[Json.NET](http://james.newtonking.com/projects/json/help/SerializingJSONFragments.html)允许使用['JObject'](http://james.newtonking。例如,com/projects/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm)。 – Groo 2012-01-13 13:43:35

0

一般来说,你可以使用某种类型的读者(的StreamReader,BinaryReader在,...)与BufferedStream在一起。