2011-08-18 4 views
4

약간의 관련 질문이 this onethis one에 약간 있습니다.부스트 직렬화 다중 객체

기본적으로 개체를 직렬화하려고합니다. 나중에 로그 파일을 병합 해제하려는 경우를 제외하고는 로그 파일과 매우 비슷합니다. 이것은 내가 처음에 모든 물건을 가지고 있지 않다는 것을 의미합니다.

이전 답변에서 동일한 아카이브를 열어두면 아카이브에 점점 더 많은 오브젝트를 추가 할 수있는 것처럼 보입니다.

하지만 어떻게 추출 할 수 있습니까? 앞을 내다보고 각 추출 전에 eof에 도달했는지 확인해야합니까? 저장 루틴에 줄 바꿈을 넣어 나중에 입력 행을 한 줄씩 읽을 수 있도록해야합니다 (xml이 줄 바꿈을 사용하기 때문에 이진 보관 파일 (및 어쩌면 텍스트)에서만 작동합니다. 이진 파일이 때때로 개행)? 어쩌면 >> 연산은 파일 끝에 도달하면 예외를 throw하고 주위에 try catch를 사용하여 무한 루프로 래핑 할 수 있습니까?

다른 종류의 개체에 대해 그렇게하고 싶다면 어떻게해야합니까? 어쩌면 모든 개체에 대한 열거 형을 가지고 직전에 열거 형을 직렬화하고, 열거 형을 기반으로 스위치를 해제 한 후 직렬화 할 수 있습니까?

감사합니다.

+0

관련 : http://stackoverflow.com/questions/6665742/boost-serialization-end-of-file – maxschlepzig

답변

2

여기는 내가 결국 한 것입니다. Nicol이 옳았는데 실제로 의도하지 않은 용도로 사용하기 때문에 먼저 포인터 추적을 사용하지 않도록 설정해야합니다. 그렇지 않으면 가짜 공유 객체가 생깁니다. 따라서 (당신이 바로이 목적을 위해 빈 가상 기반을 만들 수) 나는 또한 그냥 같은 기본 오브젝트에서 파생 된 개체를 로깅에 대한 정착으로 시작

BOOST_CLASS_TRACKING(yourDerivedClass,boost::serialization::track_never) 

의 부하합니다. 이 작업이 완료되면, 그것이 추상적으로 간주되어 있는지 확인하는 것이 중요하다 (I 모두 읽고 쓰기 (가상 소멸자를해야했고, 아직도 그것을 만든 후 아카이브와

BOOST_SERIALIZATION_ASSUME_ABSTRACT(yourBaseClass) 

등록 모든 파생 클래스를 추가)

arMsgs.template register_type<yourDerivedClass>(); 

만 (B는 C에서 파생에서 A가 파생하는 경우, B를 등록하지 않음). 최소 등록되어 모든 클래스는 장애인 추적 한 것으로 최종이 아닌 추상 클래스를 필요로 등록합니다.

마지막으로 아카이브에 추가합니다.

내가

try 
{ 
    for(;;) 
    { 
     yourBaseClass obj; 
     arObjs >> boost::serialization::make_nvp("Obj",obj); 
     //your logic 
    } 
} 
catch(boost::archive::archive_exception const& e) { } 
조금 너무 많이 잡을 수있는, 그래서 몇 가지 추가 검사를해야 할 수도 있습니다

그러나이 들어갑니다, 오히려 검사를 필요로 파일의 끝을위한 특별 토큰을 사용하는 것보다, 그들을 다시로드하려면 나를 위해 일하고있다. 장점은 적절한 종료가 중요하지 않다는 것입니다 (예 : 앱이 중간에 충돌 한 경우에도 마지막 읽을 수있는 메시지까지 처리 할 수 ​​있습니다.

2

당신이 말하는 것은 실제로 직렬화의 요점이 아닙니다. 직렬화는 쓰기 및 읽기 순서가 컴파일 타임으로 결정될 때 작동하도록 설계되었습니다. 심지어 버전 관리는 컴파일 타임입니다. 런타임 버전을 기반으로 값을 직렬화하거나 직렬화하지 않습니다. 주문은 그대로 유지됩니다.

자, 출력에 일부 토큰을 추가 할 수 있습니다.이 토큰은 클래스 유형에 매핑되는 일종의 정수 값입니다. 즉, 클래스를 스트림에 작성하기 전에 해당 클래스가 무엇인지 나타내는 정수를 작성합니다. 그런 다음 나중에 읽은 다음이를 기반으로 다음에 serialize 할 형식을 결정합니다.

하지만 문제는 결국 결국 내용이 부족하게됩니다. 그리고 연재 문서 보관소에는 실제로 "그게 전부"라고 말하는 방식이 없습니다. 그것들은 컴파일시에 정의 될 것으로 예상되므로 입력이 끝날 때까지 읽는 것은 사용자 오류로 간주됩니다. 따라서 임의의 양의 일련 화 된 데이터를 쉽게 처리 할 수 ​​없습니다.

다시 말하지만 출력에 특수 토큰을 쓸 수 있습니다. "이것은 끝입니다."

0

나는 부스트를 배우고 있는데, 당신은 부스트 ​​직렬화를 로그 파일로 사용하고 논리를 사용하여 값을 계속 추가 할 수 있다고 생각한다. 저도 같은 문제를 직면하고, 내가 잘못 아니에요 경우 코드는 다음과 같이했다 : 당신은 중괄호 (루프의 중괄호)를 닫을 때 여기

#include <iostream> 
#include <fstream> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 

int main() { 
    int two=2; 

    for(int i=0;i<10;i++) { 

     std::ofstream ofs("table.txt"); 
     boost::archive::text_oarchive om(ofs); 
     om << two; 
     two = two+30; 
     std::cout<<"\n"<<two; 
    } 

    return 0; 
} 

는, 직렬화 파일을 닫습니다. 여러 값을 저장하려면 그리고 당신은, table.txt에 기록 된 하나 개의 값을 볼 수 있습니다, 여러분의 코드는 다음과 같이해야한다 : 여기

#include <iostream> 
#include <fstream> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 

int main() { 
    int two=2; 

    { 
     std::ofstream ofs("table.txt"); 
     boost::archive::text_oarchive om(ofs); 
     for(int i=0;i<10;i++) { 

      om << two; 
      two = two+30; 
      std::cout<<"\n"<<two; 
     } 
    } 

    return 0; 
} 

당신은 중괄호 부스트 :: 직렬화를 둘러싸는 것을 알 수 있습니다 : text_oarchive는 논리의 결과를 직렬화 할 때만 닫힙니다.

+0

오른쪽. 또는 파일 스트림을 루프 내부에 추가하십시오. std :: of ofs ("table.txt", std :: ios :: app); –