10.3.2 文件读取进度

本文介绍了一个使用C++的osgDB库,通过ProgressingReadCallback类实现逐行读取文件并配合osgViewer创建动态视图的示例。代码展示了如何在读取文件时实时显示进度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <osgViewer/Viewer>
#include <osgDB/ReaderWriter>
#include <osgDB/ReadFile>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <iostream>

template<typename Elem, typename Tr = std::char_traits<Elem>>
class ProgressingStreamBuf : public std::basic_filebuf<Elem, Tr>
{
public:
    typedef std::basic_filebuf<Elem, Tr> BaseType;
    ProgressingStreamBuf(const std::string& filename)
        :BaseType(), _count(0), _readSize(0)
    {
        if (open(filename.c_str(), std::ios_base::in | std::ios_base::binary))
        {
            pubseekoff(0, std::ios_base::beg, std::ios_base::in);

        }

    }
protected:

    virtual int_type uflow()
    {
        int_type value = BaseType::uflow();
        _count++;
        _readSize += egptr() - gptr();

        if (0 == (_count % 10))
        {
            std::cout << _readSize;
        }
        else
        {
            std::cout << ".";
        }

        return value;
     }

    int _count;
    int _readSize;
};


class  ProgressingReadCallback : public osgDB::Registry::ReadFileCallback
{
public:
    typedef ProgressingStreamBuf<char> ProgressingStringBuf;
    typedef osgDB::ReaderWriter::ReadResult ReadResult;
    ProgressingReadCallback() {}

    virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::Options* option)
    {
        std::string ext = osgDB::getLowerCaseFileExtension(file);
        osgDB::ReaderWriter::ReadResult rr;
        osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(ext);

        if (rw)
        {
            std::string fileName = osgDB::findDataFile(file, option);
            if (fileName.empty()) return ReadResult::ReadResult::FILE_NOT_FOUND;

            ProgressingStringBuf* ps = new ProgressingStringBuf(fileName);
            if (!ps->is_open())
            {
                return ReadResult::ERROR_IN_READING_FILE;
            }

            std::istream s(ps);
            rr = rw->readNode(s, option);
            delete ps;
        }
        else
        {
            rr = osgDB::Registry::instance()->readNodeImplementation(file, option);
        }

        return rr;
    }
};

int main(int argc, char**argv)
{
    osg::ArgumentParser arguments(&argc, argv);
    osgDB::Registry::instance()->setReadFileCallback(new ProgressingReadCallback);
    
    osg::Node* model = osgDB::readNodeFiles(arguments);
    if (!model) model = osgDB::readNodeFile("cow.osg");

    osgViewer::Viewer viewer;
    viewer.setSceneData(model);
    return viewer.run();
}

注:

原书第74行是:

rr = rw->readNode(std::istream(ps), option);

但这样编译通不过,所以就改为了上面的第73、74行。关于std::basic_filebuf用法,参见:

std::basic_filebuf用法

运行结果如下:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值