flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 06:45
Оценка:
привет!

есть некоторый набор тестов для сериализации.
код этот, спроектирован так, чтоб юзер имел возможность создавать собственные 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 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 07:21
Оценка:
можно в требование к oarchive типу добавить метод 'flush()', который будет просто заглушкой на тех реализациях, где flush не нужен...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 07:22
Оценка:
Здравствуйте, niXman, Вы писали:

X>можно в к oarchive

т.е. к ostream
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: flush файла зная только его имя
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 26.12.13 07:25
Оценка: 20 (2) +2
Здравствуйте, niXman, Вы писали:

X>вопрос в том, каким образом я могу заставить ОС флашить данные в некоторый файл, зная только его имя?

X>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.

Во-первых, заставлять ОС бессмысленно, если речь не идёт о варианте типа внешнего NFS, к которому доступаются с двух источников и нету никакой cache coherency.
Потому что если что-то записано через OS API, то оно и может быть прочтено через него. (Точнее, я тут сужу только по Unix, про Windows не знаю. Но так как вопрос был про не привязанное к платформе решение, я могу себе это позволить)
То есть речь идёт только про рантайм процесса, насколько я понимаю. В ostream есть свой буфер.

Ну а раз так — если нет способа проитерировать все открытые ostream'ы — то проблема вряд ли решается.

Но: в C++ iostreams есть понятие tie выходного потока с входным, относящимся к тому же файлу или внешнему интерфейсу — любое чтение из входного вызывает flush выходного. Может, это поможет?

X>конечно, правильным решением было бы исправить сами тесты так, чтоб объект oarchive разрушался прежде чем создавался iarchive, но это ооочень долго


Но это лучше таки запланировать.
The God is real, unless declared integer.
Re: flush файла зная только его имя
От: uzhas Ниоткуда  
Дата: 26.12.13 08:11
Оценка: 12 (1) +2
Здравствуйте, niXman, Вы писали:

X>зы

X>конечно, правильным решением было бы исправить сами тесты так, чтоб объект oarchive разрушался прежде чем создавался iarchive, но это ооочень долго
давай лучше подумаем в этом направлении
я так понимаю, что речь идет о таких тестах, коих несколько десятков:
https://github.com/niXman/yas/blob/master/tests/base/include/vector.hpp
главные стратегии:
https://github.com/niXman/yas/blob/master/tests/base/main.cpp

как один из вариантов в передаваемой стратегии можно пропилить функции для закрытия архивов:
текущий паттерн:
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 файла, но после окончания всей сериализации
Re[2]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 08:21
Оценка:
Здравствуйте, netch80, Вы писали:

прежде всего — я согласен что ищу костыльное решение. исправлюсь.

еще подумалось, что возможно в венде есть что-то типа sync() ?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 08:27
Оценка:
Здравствуйте, uzhas, Вы писали:

U>предлагаемый:

U>
U>typename archive_traits::oarchive oa;
U>archive_traits::ocreate(oa, archive_type, io_type);
U>oa & v;
U>archive_traits::oflush(oa, archive_type, io_type);

U>typename archive_traits::iarchive ia;
U>archive_traits::icreate(ia, oa, archive_type, io_type);
U>ia & vv;

U>ensure ( v == vv );
U>

да, ты прав. это именно то, что я так не хотел делать

U>второй вариант: заменить файловые стримы на inmemory, ведь мы не файлы тестируем, а механизм сериализации.

ну.. этот исходник main.cpp — сильно отличается от того что у меня сейчас локально.
после проведенного рефакторинга, IO был отделен от самих сериализаторов. поэтому, в текущей версии добавились еще mem_ostream/mem_istream/file_ostream/file_istream, которые тоже хочется использовать в этом же тесте.

всем спасибо, переделаю-ка я лучше тесты.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: flush файла зная только его имя
От: uzhas Ниоткуда  
Дата: 26.12.13 08:53
Оценка: +1
Здравствуйте, 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;
}

успехов
Re[3]: flush файла зная только его имя
От: Ops Россия  
Дата: 26.12.13 09:24
Оценка: 15 (1) +1
Здравствуйте, niXman, Вы писали:

X>еще подумалось, что возможно в венде есть что-то типа sync() ?


_flushall() не подойдет?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[4]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 14:37
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>_flushall() не подойдет?

да, оно, спасибо!
(но я уже пошел по другому пути)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: flush файла зная только его имя
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.12.13 15:19
Оценка:
Здравствуйте, niXman, Вы писали:

X>вопрос в том, каким образом я могу заставить ОС флашить данные в некоторый файл, зная только его имя?

X>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.

1. Никаким

2. У меня есть некоторое подозрение, что эта проблема рано или поздно может всплыть и не в тестах, а "на боевом дежурстве". Как-то это неправильно, что один объект может начать читать файл, недописанный другим объектом, и этим никак нельзя управлять.
Re[3]: flush файла зная только его имя
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.12.13 15:20
Оценка:
Здравствуйте, niXman, Вы писали:

X>еще подумалось, что возможно в венде есть что-то типа sync() ?


sync() сбрасывает внутренние буфера операционной системы, а fflush() — буфера библиотеки ввода-вывода. Эти функции не эквиавалетны и не взаимозаменяемы.
Re[4]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 15:37
Оценка:
Здравствуйте, 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 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: flush файла зная только его имя
От: Pavel Dvorkin Россия  
Дата: 26.12.13 15:43
Оценка: +1
Здравствуйте, niXman, Вы писали:

Что-то мне это сомнительно. Флашинг от ОС вообще-то прозрачен. Если одна программа пишет в файл средствами ОС, а другая читает, она должна получить правильные данные.

У тебя же скорее всего дело не во флашинге от ОС, а просто в том, что в/в буферизированный, причем не от ОС, а от библиотеки С++. Тут да, вывод в файл происходит либо при заполнении буфера, либо при flush, либо при закрытии файла.

n>интересует решение не привязанное с платформе, т.е. с использованием стандартных потоков, или Си`шного файлового API.


Если устраивает С, то можно попробовать io.h, то есть функции

open
write
read

http://msdn.microsoft.com/en-us/library/40bbyw78.aspx

Этот ввод-вывод является небуферизированным.
With best regards
Pavel Dvorkin
Re[5]: flush файла зная только его имя
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.12.13 15:43
Оценка:
Здравствуйте, niXman, Вы писали:

X>можно было сделать такой вывод?


Не знаю. Наверное, надо иметь некоторое представление о том, как всё это устроено
Re[6]: flush файла зная только его имя
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.12.13 17:22
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Не знаю. Наверное, надо иметь некоторое представление о том, как всё это устроено

раз уж вы говорите про "наверное", то наверное вы знаете о чем говорите =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.