Здравствуйте, Аноним, Вы писали:
А>Привет!
А>Есть либа, в ней фунция save, сразу в файл, если имя файла не указанно, то на экран. Возможно ли создать редирект в строку?
а в чем проблема с файлом? пусть скинет во временный файл, а ты потом загонишь его целиком в строку.
Я так думаю, эта операция по определению не скоростная...
Здравствуйте, Аноним, Вы писали:
А>Привет!
А>Есть либа, в ней фунция save, сразу в файл, если имя файла не указанно, то на экран. Возможно ли создать редирект в строку?
А>
т.к целевая платформа не указана... вот такой можно завертеть финт: создать FIFO, если либа принимает имя файла или pipe (`man 2 pipe`) если она хочет файловый дескриптор, пусть плюятся в в трубу... ну а с другой стороны читай и храни как хочешь. дело происходит на *nix'ах еси чо )
А>Есть либа, в ней фунция save, сразу в файл, если имя файла не указанно, то на экран. Возможно ли создать редирект в строку?
Возможно забить костыль с использованием pipes.
Собственно, всё просто: создаёшь pipe и один конец конец передаёшь функции, из другого читаешь строку.
Pipe можно создать именованным и передать в функцию save его имя, либо неименнованным, подменив на время дескриптор stdout на дескриптор pipe. Первый вариант чуточку сложнее, но более удобный, так как он не трогает глобальный stdout.
Единственная проблема с pipe состоит в том, что если объём записываемых данных велик, то при ненедлежащем использовании можно самому себе сделать deadlock. Впрочем, так же очевидно, что его можно надёжно избежать (простейший вариант — вычитывать содержимое pipe в другой нити чем вызываемая функция). Ну либо отказаться от pipe в пользу временных файлов — у них самоблокировок не будет.
А>
Записать в файл (и как частный случай, в stdout) можно десятком различных способов. Вполне ожидаемо, что манипуляции с std::cout никак не отобразятся на другой библиотеке, так как она просто может не использовать именно этот экземпляр std::cout для вывода.
J>а в чем проблема с файлом? пусть скинет во временный файл, а ты потом загонишь его целиком в строку. J>Я так думаю, эта операция по определению не скоростная...
Проблемы нет.Старый проект разросся. Проект не мой с открытым кодом, но на некоторые либы исходники отсутствуют(.lib & .h). Сейчас программа обрабатывает вход соединение результатом которого является файл, который по шедуллеру отправляется на другой сервер, потом приходит файл с уд.сервера — опять в директорию, опять считывание содержимого и отсылка инициатору всей этой затеи... скорее всего изза возросшего кол-ва вход соединений все начало тормозить. Вот и хотел попробовать и все переделать. Писать свою либу не вариант там вшита гостовская криптозащита.
Здравствуйте, zaufi, Вы писали:
Z>т.к целевая платформа не указана... вот такой можно завертеть финт: создать FIFO, если либа принимает имя файла или pipe (`man 2 pipe`) если она хочет файловый дескриптор, пусть плюятся в в трубу... ну а с другой стороны читай и храни как хочешь. дело происходит на *nix'ах еси чо )
Здравствуйте, watch-maker, Вы писали:
WM>Возможно забить костыль с использованием pipes. WM>Собственно, всё просто: создаёшь pipe и один конец конец передаёшь функции, из другого читаешь строку. WM>Pipe можно создать именованным и передать в функцию save его имя, либо неименнованным, подменив на время дескриптор stdout на дескриптор pipe. Первый вариант чуточку сложнее, но более удобный, так как он не трогает глобальный stdout. WM>Единственная проблема с pipe состоит в том, что если объём записываемых данных велик, то при ненедлежащем использовании можно самому себе сделать deadlock.
Суть понятна, но я с pipe не работал — может посоветуете что можно почитать для результативного самообразования.
WM>Впрочем, так же очевидно, что его можно надёжно избежать (простейший вариант — вычитывать содержимое pipe в другой нити чем вызываемая функция).
Т.е. создать поток и читать с другой стороны канала?
WM>Ну либо отказаться от pipe в пользу временных файлов — у них самоблокировок не будет.
Я выше описал почему решил уйти от файлов.
WM>Записать в файл (и как частный случай, в stdout) можно десятком различных способов. Вполне ожидаемо, что манипуляции с std::cout никак не отобразятся на другой библиотеке, так как она просто может не использовать именно этот экземпляр std::cout для вывода.
Посмотрел файл .h либы, там вообщем если save без параметров то выполняется save(stdout), если с параметром то save(FILE* file)
Здравствуйте, iking, Вы писали:
I>Суть понятна, но я с pipe не работал — может посоветуете что можно почитать для результативного самообразования.
Хоть мне и приходилось использовать именованые pipe под Windows, но учил я работу с ними в Unix. Так что можно, если сам не найдешь ничего, идею посмотреть в любой книге по межпроцессному взаимодействию, а уж детали реализации смотреть в MSDN.
WM>>Впрочем, так же очевидно, что его можно надёжно избежать (простейший вариант — вычитывать содержимое pipe в другой нити чем вызываемая функция). I>Т.е. создать поток и читать с другой стороны канала?
Да. В pipe все данные хранятся в буферах в памяти. И если код выглядит так
То если на шаге два буфер заполнится, то запись будет приостановлена до момента, пока в нём не появится место, но так как это может произойти только в пункте 3, то получаем блокировку.
Вынос пункта 3 в отдельный поток — простейший путь. Конечно, есть и другие варианты, но они требуют немного менять логику записи в пункте 2, что, как я понял, тебе не подходит.
Ну или, если известно, что размер записываемых данных заведомо меньше размера буфера, то можно в отдельный поток ничего не выносить.
WM>>Записать в файл (и как частный случай, в stdout) можно десятком различных способов. Вполне ожидаемо, что манипуляции с std::cout никак не отобразятся на другой библиотеке, так как она просто может не использовать именно этот экземпляр std::cout для вывода.
I>Посмотрел файл .h либы, там вообщем если save без параметров то выполняется save(stdout), если с параметром то save(FILE* file)
Ну так stdout ничего не знает о std::cout. Тут как раз std::cout использует stdout для вывода, а не наоборот. Попробуй его поменять.
А вообще, если у тебя в функцию передаётся не имя файла, а FILE*, то можно попробовать через него что-то упростить. В unix можно функцией fdopen сразу открыть неименованный pipe и получить нужный FILE* для работы. Так же есть функции open_memstream и fmemopen, которые открывают участок в памяти как FILE*, что делает решение всей задачи просто элементарным. К сожалению, в Windows аналога последних функций мне неизвестно, а вариант с fdopen возможно содержит какие-нибудь подводные камни, но, думаю, проверить его стоит.
WM> В unix можно функцией fdopen сразу открыть неименованный pipe и получить нужный FILE* для работы.
Собственно, под msvc можно сделать аналогично, добавив немного магии с дескрипторами:
Здравствуйте, watch-maker, Вы писали:
А>>Есть либа, в ней фунция save, сразу в файл, если имя файла не указанно, то на экран. Возможно ли создать редирект в строку?
WM>Единственная проблема с pipe состоит в том, что если объём записываемых данных велик, то при ненедлежащем использовании можно самому себе сделать deadlock.
Это не единственная проблема. Все зависит от того, как работает код записи. Если это просто набор write-ов по дескриптору — все нормально, но если там используется запись по позиции (к примеру, создается мегабайтный файл, забивается целиком нулями, потом 2-й килобайт заполняется неприличными словами), то пайпы, очевидно, не сработают.
Добрая половина юниксовых утилит, ожидающих файлы, не работает с именованными пайпами.
Здравствуйте, Аноним, Вы писали:
А>Привет!
А>Есть либа, в ней фунция save, сразу в файл, если имя файла не указанно, то на экран. Возможно ли создать редирект в строку?