2012-01-13 5 views
1

전체 파일을 메모리에로드하지 않고이 작업을 수행 할 수 있습니까? 그렇다면 무엇을 제안 하시겠습니까?직렬화 된 객체 파일 쿼리

클래스 구현 :

[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); 
} 
+0

XML로 직렬화됩니까? – Groo

+0

@Groo 아니요, XML로 직렬화되지 않습니다. 내 질문에 클래스 구현을 추가했습니다. – onatm

+0

직렬화는 실제로 메모리에 이진 파일을로드하지 않고 스트림을 통과하여 즉시 역 직렬화합니다. 하지만이 작업이 끝나면 전체 객체가 메모리에로드되어 일부만로드하려고합니다. 그게 어떤 부분일까요? 단일 속성? 그리고 "쿼리"라고 할 때 LINQ 쿼리를 참조합니까? 이 경우에는 코드에서 볼 수없는 개체 모음이 있어야하기 때문입니다. – Groo

답변

1

컬렉션을 한 번에 하나의 개체에 대해 deserialize하려면 한 번에 하나씩 serialize해야합니다. 당신의 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"); 

약간 더 복잡한 경우가있을 수 있습니다

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

이 그럼 당신은 간단하게 작성할 수 있습니다

가장 간단한 방법은 자신의 제네릭 클래스를 정의하는 것입니다. 이 경우 ISerializable을 구현해야하지만 원리는 비슷합니다.

참고로 일반적으로 약자는 복수형으로 이름을 지정하지 않습니다 (즉, Cars의 이름은 Car이어야합니다).

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. co.kr/projects/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm)과 같이 사용할 수 있습니다. – Groo

0

일반적으로 BufferedStream과 함께 일종의 리더 (StreamReader, BinaryReader, ...)를 사용할 수 있습니다.