2015-04-25 2 views
1

Я решил прочитать/записать в файл с использованием сериализации; однако он только прав несколько элементов. Наши элементы динамически распределяются через тестовые скрипты, после того как все они помещены в вектор, они затем будут записаны в скрипт. Ниже приведен код в нашей основной функции - случаи коммутатора, где мы вызываем функции для чтения и записи объектов, и, наконец, функции, в которых мы пытаемся записать и прочитать файл. Я не знаю, почему это только чтение в пара-объекте, поэтому любая помощь будет отличной!C++: запись и чтение объектов в двоичный файл

//////////////////////////////////////////////////////// 
// Main 
int main(int argc, char *argv[]) { 
    std::string optionInput; 
    const char *const file_name = "data.dat"; 
    menuDisplay(); 

    while (loopBool) { 
     std::cin.clear(); 
     if (selectedObject == SELECT_INIT) { 
      std::cout << std::endl << "Menu (No Item): "; 
     } else { 
      std::cout << std::endl << "Item " << selectedObject << " Menu: "; 
     } 
     try { 
      optionInput = menuInput(); 
     } catch (const Input_Error &) { 
      std::cout << "Input error detected. Exiting.\n"; 
      break; 
     } 

     catch (...) { 
      std::cout << "You should not be seeing this error message.\n"; 
      break; 
     } 
     std::cout << optionInput[0] << std::endl; 
     optionSelect(optionInput[0]); 
    } 

    std::cout << "Exiting\n" << std::endl; 
} 

//////////////////////////////////////////////////////// 
// Case 'W' 
case 'W': { 
    // Writes authors to a file 
    std::ofstream aSaveFile("authors.dat"); 
    boost::archive::text_oarchive aArchiveOut(aSaveFile); 
    aArchiveOut << authorObject; 

    // Writes mediaItem objects to a file 
    std::ofstream mSaveFile("items.dat"); 
    boost::archive::text_oarchive mArchiveOut(mSaveFile); 

    ioMediaInfo itemSender; 
    for (int mediaWrite = 0; mediaWrite < mediaObject.size(); mediaWrite++) { 
     itemSender.assignVariables(mediaObject[mediaWrite]); 
     mArchiveOut << itemSender; 
    } 
    break; 
} 

//////////////////////////////////////////////////////// 
// Case 'Z' 
case 'Z': { 
    // Reads in authors to author array 
    std::ifstream aReadFile("authors.dat"); 

    boost::archive::text_iarchive aArchiveIn(aReadFile); 
    aArchiveIn >> authorObject; 

    // Reads in mediaItems 

    std::ifstream mReadFile("items.dat"); 

    boost::archive::text_iarchive mArchiveIn(mReadFile); 

    std::string itemType; 
    ioMediaInfo itemReciever; 

    // for (int mediaRead = 0; mediaRead < 20; mediaRead++) 
    // { 

    mArchiveIn >> itemReciever; 

    // Checks type of current object and creates a new mediaItem object in the vector to store it 

    // TODO: Break case statement repetition into functions for greater code reuse 

    itemType = itemReciever.getType(); 

    switch (itemType[0]) { 
    case '*': { 
     mediaObject.push_back(new mediaInfo()); 
     selectedObject++; 
     mediaObject[selectedObject]->setName(itemReciever.getName()); 
     mediaObject[selectedObject]->setYear(itemReciever.getYear()); 
     mediaObject[selectedObject]->setEmpty(itemReciever.getEmpty()); 
     break; 
    } 
    case 'B': { 
     mediaObject.push_back(new bookInfo()); 
     mediaObject[selectedObject]->setName(itemReciever.getName()); 
     mediaObject[selectedObject]->setEmpty(itemReciever.getEmpty()); 
     break; 
    } 
    case 'V': { 
     mediaObject.push_back(new videoInfo()); 
     mediaObject[selectedObject]->setName(itemReciever.getName()); 
     mediaObject[selectedObject]->setEmpty(itemReciever.getEmpty()); 
     break; 
    } 
    case 'M': { 
     mediaObject.push_back(new musicInfo()); 
     mediaObject[selectedObject]->setName(itemReciever.getName()); 
     mediaObject[selectedObject]->setEmpty(itemReciever.getEmpty()); 
     break; 
    } 
    default: { break; } 
    } 

    // } 
    break; 
} 

//////////////////////////////////////////////////////// 
// assignVariable where we write to file 
void ioMediaInfo::assignVariables(mediaInfo *originalMediaObject) { 
    mediaItemName_ = originalMediaObject->getName(); 
    mediaItemYear_ = originalMediaObject->getYear(); 
    mediaItemPageNum_ = originalMediaObject->getPage(); 
    mediaItemPrint_ = originalMediaObject->getPrint(); 
    mediaItemValue_ = originalMediaObject->getValue(); 
    mediaItemType_ = originalMediaObject->getType(); 
    isEmpty_ = originalMediaObject->isEmpty(); 
    // mediaItemAuthor_ = originalMediaObject->getAuthor(); 
} 

//////////////////////////////////////////////////////// 
// Where we read the file 
void ioMediaInfo::printData() { std::cout << mediaItemName_ << std::endl; } 
+0

You как представляется, отсутствует часть вашего кода. Есть два оператора case, которые находятся вне функции. Это намеренно? – phantom

+0

@Phantom Я просто предоставил код, который, как я чувствовал, был уместным для чтения и записи в файлы. У меня есть целая инструкция switch, которая отличается от этих случаев. Если вы хотите увидеть больше кода, я могу его предоставить. –

+0

Обязательно добавьте еще код. В классе нет сериализуемого класса. – sehe

ответ

0

Я думаю, что вы смешиваете парадигмы. Это очень похоже на код, взятый из плохого образца C-стиля, в котором используется массив фиксированной длины выделенных вручную полиморфных классов ioMediaItem (чтобы добавить оскорбление к травме, содержать и сериализовывать ручной ввод строки mediaInfoType_).

Тогда вы ведете чудовищно сложный цикл, чтобы читать элементы и поддерживать инварианты коллекции (предположительно, что type=='*' подразумевает isEmpty() и что вектор mediaInfoObjects не содержит недействительные объекты и т.д.).

Ускоренная сериализация была сделана так, что вы не должны беспокоиться об этих вещах. Зачем использовать сложную библиотеку, если вы собираетесь делать все неуклюжие управляющие и детские шаги в конце концов?

Просто отпустите. Вот вкус того, что это может быть, как:

Live On Coliru

#include <iostream> 
#include <fstream> 
#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 

#include <boost/serialization/serialization.hpp> 
#include <boost/serialization/vector.hpp> 
#include <boost/serialization/variant.hpp> 
#include <boost/serialization/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 

namespace Media { 
    struct Author { 
     std::string name; 
     Author(std::string name = "") : name(std::move(name)) {} 
    }; 

    using AuthorRef = boost::shared_ptr<Author>; 

    struct CommonInfo { 
     std::string name; 
     int   year; 
     AuthorRef author; 
    }; 

    struct BookInfo : CommonInfo { 
     BookInfo() = default; 

     int pageNum; 
     int print; 
     int value; 

     BookInfo(CommonInfo ci, int pageNum, int print, int value) : 
      CommonInfo(ci), pageNum(pageNum), print(print), value(value) 
     { } 
    }; 

    struct VideoInfo : CommonInfo { 
     VideoInfo(CommonInfo ci = {}) : CommonInfo(ci) { } 
    }; 

    struct MusicInfo : CommonInfo { 
     MusicInfo(CommonInfo ci = {}) : CommonInfo(ci) { } 
    }; 

    using Object = boost::variant<BookInfo, MusicInfo, VideoInfo>; 
    using Catalog = std::vector<Object>; 

    ////// serialization methods 
    static inline std::ostream& operator<<(std::ostream& os, CommonInfo const& ci) { return os << ci.name << " (" << ci.author->name << ")"; } 

    // out-of-class serialization 
    template <typename Ar> void serialize(Ar& ar, VideoInfo& o, unsigned) { ar & boost::serialization::base_object<CommonInfo>(o); } 
    template <typename Ar> void serialize(Ar& ar, MusicInfo& o, unsigned) { ar & boost::serialization::base_object<CommonInfo>(o); } 
    template <typename Ar> void serialize(Ar& ar, CommonInfo&o, unsigned) { 
     ar & o.name & o.year & o.author; 
    } 
    template <typename Ar> void serialize(Ar& ar, Author& o, unsigned) { 
     ar & o.name; 
    } 
    template <typename Ar> void serialize(Ar& ar, BookInfo& o, unsigned) { 
     ar & boost::serialization::base_object<CommonInfo>(o) 
      & o.pageNum 
      & o.print 
      & o.value 
      ; 
    } 
} 

struct Library { 
    std::vector<Media::AuthorRef> authors; // to allow unreferenced authors 
    Media::Catalog catalog; 

    static Library makeSample(); 

    static Library load(std::string const& fname); 
    void save(std::string const& fname) const; 

    template <typename Ar> void serialize(Ar&ar,unsigned) { 
     ar & authors & catalog; 
    } 
}; 

//////////////////////////////////////////////////////// 
// Main 
int main() { 
    Library::makeSample().save("authorsAndItems.dat"); 

    auto cloned = Library::load("authorsAndItems.dat"); 

    for (auto& obj : cloned.catalog) 
     std::cout << obj << "\n"; 
} 

using namespace Media; 

Library Library::makeSample() { 
    using boost::make_shared; 
    // shared author 
    auto multaScripserat = make_shared<Author>("Scripserat, Multa T."); 

    return { 
     { 
      multaScripserat, 
      boost::make_shared<Author>(Author{"Sufferer, A."}), // no books/music survived 
     }, 
     { 
      BookInfo { CommonInfo { "Title 1", 1999, multaScripserat }, 453, 7, 3 }, 
      BookInfo { CommonInfo { "Title 2", 2011, multaScripserat }, 200, 5, 1 }, 
      MusicInfo { { "Pop Album", 1972, make_shared<Author>("Beatles, The") } }, 
      MusicInfo { { "Title 2", 2011, multaScripserat } }, 
      VideoInfo { { "The Battleship Potemkin", 1925, make_shared<Author>("Eisenstein, Sergei") } }, 
     } 
    }; 
} 

void Library::save(std::string const& fname) const { 
    std::ofstream ofs(fname, std::ios::binary); 
    boost::archive::binary_oarchive oa(ofs); 

    oa << *this; 
} 

Library Library::load(std::string const& fname) { 
    std::ifstream ifs(fname, std::ios::binary); 
    boost::archive::binary_iarchive ia(ifs); 

    Library lib; 
    ia >> lib; 

    return lib; 
} 

гравюр

Title 1 (Scripserat, Multa T.) 
Title 2 (Scripserat, Multa T.) 
Pop Album (Beatles, The) 
Title 2 (Scripserat, Multa T.) 
The Battleship Potemkin (Eisenstein, Sergei) 

шестнадцатеричного файла authorsAndItems.dat:

0000000: 1600 0000 0000 0000 7365 7269 616c 697a ........serializ 
0000010: 6174 696f 6e3a 3a61 7263 6869 7665 0b00 ation::archive.. 
0000020: 0408 0408 0100 0000 0000 0000 0000 0000 ................ 
0000030: 0000 0200 0000 0000 0000 0100 0000 0001 ................ 
0000040: 0000 0003 0001 0000 0000 0000 0000 1400 ................ 
0000050: 0000 0000 0000 5363 7269 7073 6572 6174 ......Scripserat 
0000060: 2c20 4d75 6c74 6120 542e 0300 0100 0000 , Multa T....... 
0000070: 0c00 0000 0000 0000 5375 6666 6572 6572 ........Sufferer 
0000080: 2c20 412e 0000 0000 0005 0000 0000 0000 , A............. 
0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000a0: 0000 0000 0000 0000 0700 0000 0000 0000 ................ 
00000b0: 5469 746c 6520 31cf 0700 0003 0000 0000 Title 1......... 
00000c0: 00c5 0100 0007 0000 0003 0000 0000 0000 ................ 
00000d0: 0007 0000 0000 0000 0054 6974 6c65 2032 .........Title 2 
00000e0: db07 0000 0300 0000 0000 c800 0000 0500 ................ 
00000f0: 0000 0100 0000 0100 0000 0000 0000 0009 ................ 
0000100: 0000 0000 0000 0050 6f70 2041 6c62 756d .......Pop Album 
0000110: b407 0000 0300 0200 0000 0c00 0000 0000 ................ 
0000120: 0000 4265 6174 6c65 732c 2054 6865 0100 ..Beatles, The.. 
0000130: 0000 0700 0000 0000 0000 5469 746c 6520 ..........Title 
0000140: 32db 0700 0003 0000 0000 0002 0000 0000 2............... 
0000150: 0000 0000 1700 0000 0000 0000 5468 6520 ............The 
0000160: 4261 7474 6c65 7368 6970 2050 6f74 656d Battleship Potem 
0000170: 6b69 6e85 0700 0003 0003 0000 0012 0000 kin............. 
0000180: 0000 0000 0045 6973 656e 7374 6569 6e2c .....Eisenstein, 
0000190: 2053 6572 6765 69       Sergei 
Смежные вопросы