2012-01-13 18 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在一起。