есть некоторый набор тестов для сериализации.
код этот, спроектирован так, чтоб юзер имел возможность создавать собственные IO классы. единственное требование к таким классам заключается в том, что у ostream класса должен присутствовать метод 'std::size_t write(const void *ptr, const std::size_t)', а у istream класса — 'std::size_t read(void *ptr, const std::size_t)'.
с этим моментом все в порядке. проблема с тестами этого кода.
тесты устроены так, что сначала в oarchive сериализуются некоторые данные, а потом iarchive их должен десериализовать, и, после этого, сравниваем с исходными.
так вот проблема заключается в том, объект типа oarchive не разрушается в тот момент когда создается объект типа iarchive. таким образом, данные файла созданного объектом oarchive оказываются не сброшенными на диск, и, как следствие — при создании объекта iarchive, он бросает исключение о том, что нет данных для десериализации, что есть верно.
вопрос в том, каким образом я могу заставить ОС флашить данные в некоторый файл, зная только его имя?
интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.
благодарен.
зы
конечно, правильным решением было бы исправить сами тесты так, чтоб объект oarchive разрушался прежде чем создавался iarchive, но это ооочень долго
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>вопрос в том, каким образом я могу заставить ОС флашить данные в некоторый файл, зная только его имя? X>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.
Во-первых, заставлять ОС бессмысленно, если речь не идёт о варианте типа внешнего NFS, к которому доступаются с двух источников и нету никакой cache coherency.
Потому что если что-то записано через OS API, то оно и может быть прочтено через него. (Точнее, я тут сужу только по Unix, про Windows не знаю. Но так как вопрос был про не привязанное к платформе решение, я могу себе это позволить)
То есть речь идёт только про рантайм процесса, насколько я понимаю. В ostream есть свой буфер.
Ну а раз так — если нет способа проитерировать все открытые ostream'ы — то проблема вряд ли решается.
Но: в C++ iostreams есть понятие tie выходного потока с входным, относящимся к тому же файлу или внешнему интерфейсу — любое чтение из входного вызывает flush выходного. Может, это поможет?
X>конечно, правильным решением было бы исправить сами тесты так, чтоб объект oarchive разрушался прежде чем создавался iarchive, но это ооочень долго
как один из вариантов в передаваемой стратегии можно пропилить функции для закрытия архивов:
текущий паттерн:
typename archive_traits::oarchive oa;
archive_traits::ocreate(oa, archive_type, io_type);
oa & v;
typename archive_traits::iarchive ia;
archive_traits::icreate(ia, oa, archive_type, io_type);
ia & vv;
ensure ( v == vv );
предлагаемый:
typename archive_traits::oarchive oa;
archive_traits::ocreate(oa, archive_type, io_type);
oa & v;
archive_traits::oflush(oa, archive_type, io_type);typename archive_traits::iarchive ia;
archive_traits::icreate(ia, oa, archive_type, io_type);
ia & vv;
ensure ( v == vv );
второй вариант: заменить файловые стримы на inmemory, ведь мы не файлы тестируем, а механизм сериализации. если хочется сбросить на файл, то опять же это можно сделать из inmemory файла, но после окончания всей сериализации
да, ты прав. это именно то, что я так не хотел делать
U>второй вариант: заменить файловые стримы на inmemory, ведь мы не файлы тестируем, а механизм сериализации.
ну.. этот исходник main.cpp — сильно отличается от того что у меня сейчас локально.
после проведенного рефакторинга, IO был отделен от самих сериализаторов. поэтому, в текущей версии добавились еще mem_ostream/mem_istream/file_ostream/file_istream, которые тоже хочется использовать в этом же тесте.
всем спасибо, переделаю-ка я лучше тесты.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>это именно то, что я так не хотел делать
кстати1, метод Flush гармонично вписывается в интерфейс абстракции OutputStream, так что не надо его бояться
X>всем спасибо, переделаю-ка я лучше тесты.
кстати2, выделенный фрагмент кода повторяется во многих тестах, можно было бы вытащить это в отдельную функцию и вызывать ее из каждого теста
void archive_traits::write_read_test(V v, const char* message)
{
oarchive oa;
ocreate(oa, archive_type, io_type);
oa & v;
oflush(oa, archive_type, io_type);
Data vv;
iarchive ia;
icreate(ia, oa, archive_type, io_type);
ia & vv;
if ( v != vv )
throw message;
}
Здравствуйте, niXman, Вы писали:
X>вопрос в том, каким образом я могу заставить ОС флашить данные в некоторый файл, зная только его имя? X>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.
1. Никаким
2. У меня есть некоторое подозрение, что эта проблема рано или поздно может всплыть и не в тестах, а "на боевом дежурстве". Как-то это неправильно, что один объект может начать читать файл, недописанный другим объектом, и этим никак нельзя управлять.
Здравствуйте, niXman, Вы писали:
X>еще подумалось, что возможно в венде есть что-то типа sync() ?
sync() сбрасывает внутренние буфера операционной системы, а fflush() — буфера библиотеки ввода-вывода. Эти функции не эквиавалетны и не взаимозаменяемы.
Здравствуйте, Pzz, Вы писали:
Pzz>sync() сбрасывает внутренние буфера операционной системы, а fflush() — буфера библиотеки ввода-вывода. Эти функции не эквиавалетны и не взаимозаменяемы.
как из этого:
sync() causes all buffered modifications to file metadata and data to be written to the underlying file systems.
можно было сделать такой вывод?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Что-то мне это сомнительно. Флашинг от ОС вообще-то прозрачен. Если одна программа пишет в файл средствами ОС, а другая читает, она должна получить правильные данные.
У тебя же скорее всего дело не во флашинге от ОС, а просто в том, что в/в буферизированный, причем не от ОС, а от библиотеки С++. Тут да, вывод в файл происходит либо при заполнении буфера, либо при flush, либо при закрытии файла.
n>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.
Если устраивает С, то можно попробовать io.h, то есть функции
Здравствуйте, Pzz, Вы писали:
Pzz>Не знаю. Наверное, надо иметь некоторое представление о том, как всё это устроено
раз уж вы говорите про "наверное", то наверное вы знаете о чем говорите =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)