2013-10-04 3 views
0

просто быстрый вопрос относительно boost :: iostream :: filtering_ostream().Ошибка boost filter_ostream при возврате из функции

У меня есть функция, которая (внутренне) создает shared_ptr для boost :: iostream :: filtering_ostream и возвращает общий указатель на std :: ostream.

Всякий раз, когда я не использую компрессор в функции, все работает нормально, но как только я добавляю компрессор, выходной файл становится поврежденным. Если я напишу текст в функции getOutputStreamComp, тогда все будет работать.

Пример ниже просто записывает некоторые цифры в файл, как POC.

#include <iostream> 
#include <string> 
#include <fstream> 
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/device/file.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 
#include <boost/shared_ptr.hpp> 

boost::shared_ptr<std::ostream> getOutputStream(const std::string& fileName) 
{ 
    boost::shared_ptr<boost::iostreams::filtering_ostream> out(boost::shared_ptr<boost::iostreams::filtering_ostream>(new boost::iostreams::filtering_ostream())); 
    out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary); 

    return out; 
} 

boost::shared_ptr<std::ostream> getOutputStreamComp(const std::string& fileName) 
{ 
    boost::shared_ptr<boost::iostreams::filtering_ostream> out(boost::shared_ptr<boost::iostreams::filtering_ostream>(new boost::iostreams::filtering_ostream())); 
    out->push(boost::iostreams::gzip_compressor()); 
    out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary); 

    return out; 
} 

int main(int argc, char** argv) 
{ 
    boost::shared_ptr<std::ostream> outFile  = getOutputStream("test.txt"); 
    boost::shared_ptr<std::ostream> outFileComp = getOutputStreamComp("testcomp.txt.gz"); 

    // This file is fine. 
    for (size_t i(0); i < 10000; ++i) 
    { 
     *outFile << "i: " << i << std::endl; 
    } 

    // This file is corrupt. 
    for (size_t i(0); i < 10000; ++i) 
    { 
     *outFileComp << "i: " << i << std::endl; 
    } 
} 

Любые идеи, которые могли бы быть, были бы с благодарностью приняты!

Спасибо,

Dave

ответ

1

Хорошо, так что я нашел эту проблему, с помощью от Cubbi - следующую строку (которая появляется дважды):

out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary); 

должно быть:

out->push(boost::iostreams::file_sink(fileName,std::ofstream::binary)); 

код еще компиляции, поэтому я, вероятно, установил флаг где-то в файле filtering_ostream, что, возможно, привело к дальнейшим проблемам.

Это исправление позволяет создать файл, как ожидается.

1

После исправления опечаток (*outFile и *outFileComp), я не могу воспроизвести это: компиляции с г ++ 4.8.1/наддува 1,53, она работает и производит два хороших файлов: test.txt с 10 000 строк (размер файла 78 890) и testcomp.txt.gz (размер файла 22 064), который распаковывается с помощью gunzip в точную копию test.txt.

Возможно, в вашей реальной программе вы попытались изучить файл до окончания программы (или, по крайней мере, до того, как последняя ссылка на shared_ptr исчезла)? Общим результатом сжатых фильтрованных потоков является то, что промывка outFileComp, как и в случае с std::endl, пока не заставляет полную запись сжатого файла.

+0

Извинения за опечатку, функции getOutputStream и getOutputStreamComp точно скопированы из моего кода, но остальное было просто для примера. Будет больше думать и тип меньше в следующий раз. Возможно, вы правы с вашей догадкой - я проведу через него еще несколько раз и посмотрю, смогу ли я понять, что случилось. Я использую VS2012 Express, если это помогает. Спасибо, что посмотрели, это очень ценится! – DaveM

+0

Итак, я думаю, что я понял это - там была опечатка, когда нажав file_sink на filtering_ostream, но тот, который позволил компилировать код. Я написал следующее: 'out-> push (boost :: iostreams :: file_sink (fileName), std :: ofstream :: binary);', , когда это должно было быть: 'out-> push (boost :: iostreams :: file_sink (fileName, std :: ofstream :: binary)); ' Кажется, что проблема на моей машине для Windows, и все отлично работает. Еще раз спасибо за ваш вклад Cubbi, я благодарен, что вы нашли время! – DaveM

+0

@DaveM Это было действительно легко пропустить!Я тестировал на linux box, где текст и бинарные файлы не отличаются, поэтому, конечно, ваша программа работала для меня как есть. Вы можете отправить свой результат в качестве ответа и принять это вместо этого, чтобы сделать его более полезным для будущих читателей. – Cubbi

Смежные вопросы