2012-01-13 8 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

+0

@Grooではなく、XMLにシリアル化されていません。私は私の質問にクラスの実装を追加しました。 – onatm

+0

シリアライゼーションは実際にメモリ内のバイナリファイルをロードせず、ストリームを通過して即座にデシリアライズします。しかし、これが行われた後、オブジェクト全体がメモリにロードされます。そのため、オブジェクトの一部だけをロードしたいと思うようになります。それはどの部分ですか?単一のプロパティ?そして、「照会」と言ったら、LINQ照会を参照していますか?その場合、コードからは見えないオブジェクトのコレクションが存在するはずです。 – Groo

答えて

1

コレクションを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を実装する必要がありますが、原則は似ています。

通常の規則では、複数のエンティティに名前を付けることはありません(CarsCarとする必要があります)。

2

あなたがseqentiallyストリームから読み込みますSAXパーサー(XmlReader class)を、使用できるXMLためにシリアライズした場合。

+0

私はXMLにシリアル化したくない。 JSONのシリアル化を選択するとどうなりますか? – onatm

+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

0

通常、BufferedStreamと一緒に何らかの種類のリーダー(StreamReader、BinaryReader、...)を使用できます。

関連する問題