Основная проблема заключается в том, что процесс не полностью меняется.
std::ofstream ofs; // presumed open
ofs << v1 << v2 << v3 << v4 << v5; // some different variables
ofs.close();
std::ifsteram ifs; // open to same stream
ifs >> r1 >> r2 >> r3 >> r4 >> r5; // variables of same types as above
Вы можете подумать, что это сработает, но, вероятно, не сработает. При записи в текстовый поток формальных разделителей не существует, их необходимо вручную вставить, чтобы узнать, когда один токен заканчивается, а другой начинается.
Обычно в отношении строк предполагается, что они не содержат символов новой строки или символов табуляции, а затем при чтении они часто используются в качестве разделителя.
Самый «идеальный» способ написать строку, чтобы вы могли ее прочитать, - записать ее размер, а затем ее содержимое. Даже если вы используете iostream:
os << str.size() << str;
не будет ставить пробел между размером и содержимым, поэтому, если содержимое начинается с цифры, у вас возникают проблемы при ее чтении позже.
os << str.size() << '\t' << str;
будет работать.
Что касается чтения больших коллекций, вам лучше всего использовать строки со знаком табуляции или со строкой и использовать std :: getline в цикле. istream_iterator просто не будет работать, если в вашей строке есть пробелы.
Ваша альтернатива - сначала прочитать в разделе заголовка:
- количество строк
- размер каждой строки.
Затем считывайте данные только из большого буфера, и, зная, сколько вы собираетесь прочитать и их размеры, вы можете предварительно распределить свои буферы.
Запись двоичного кода означает запись необработанных байтов в файл. Это похоже на функцию fwrite в C, за исключением того, что вы не указываете два размера, только один размер, который является числом байтов, которые вы напишите.
Вам необходимо решить вопросы, которые:
- Windows вставит для вас символ ASCII 13 перед каждым символом ASCII 10, который вы пишете, если вы не открываете поток для двоичного файла.
- Если вы пишете числа побайтно, будьте осторожны с порядковыми номерами и размерами, если они будут прочитаны обратно. Лучший способ решить эту проблему - поместить порядковый номер в заголовочный раздел вашего вывода, а затем записать в собственном формате. Предполагается, что большую часть времени это будет платформа, которую вы используете, поэтому она более эффективна.
int x;
os.write( &x, sizeof(int) );
Большим плюсом написания чисел таким образом является не только то, что он более эффективен во времени, но также нет необходимости вставлять какие-либо разделители, поэтому их обратное чтение становится относительно простым.
Недостатком является то, что вам потребуется специальный интерпретатор для чтения файла обратно, если в нем есть какие-либо ошибки.
В любом случае, это проблемы.
Элегантное решение для всего этого предоставляется в составе библиотеки наддува с архивом и сериализацией .
Вы можете писать в текстовом или двоичном режиме, и он восстановит способ, которым вы его сохранили. Он даже будет писать указатели «глубоко» для вас.