You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何std::istream读操作未调用自定义filebuf的xsgetn()方法?

问题

我希望在通过std::istream读取关联文件、以及通过std::ostream写入关联文件时收到通知。为此我派生了自定义std::filebuf,并重写xsgetn()和xsputn()函数,让它们先向控制台输出信息再调用父类实现。测试代码中,写操作成功触发了自定义的xsputn(),但读操作(使用getline)虽执行成功,却从未调用自定义的xsgetn()。我还尝试重载std::basic_filebuf::uflow()和std::basic_filebuf::underflow(),这两个函数在读取时能成功触发,想了解xsgetn()未被调用的原因。

测试代码如下:

#include <iostream>
#include <fstream>
#include <cstdio>

class MyFileBuff : public std::filebuf
{
public:
    std::streamsize xsgetn(char_type* s, std::streamsize count) override
    {
        std::cout << "using my xsgetn()" << std::endl;
        return std::filebuf::xsgetn(s, count);
    }

    std::streamsize xsputn(const char_type* s, std::streamsize count) override
    {
        std::cout << "using my xsputn()" << std::endl;
        return std::filebuf::xsputn(s, count);
    }

    using std::filebuf::basic_filebuf;
};


int main()
{
    //open file
    FILE* filePtr{ nullptr };
    fopen_s(&filePtr, "text.txt", "w+");

    //associate file with instance of custom std:filebuff
    MyFileBuff fileBuff(filePtr);

    //initalize i/o streams with file buffer
    std::istream myIStream(&fileBuff);
    std::ostream myOStream(&fileBuff);

    //output to file
    myOStream << "hello world" << std::endl;

    const short buffSize{ 1024 };
    char buff[buffSize];
    myIStream.seekg(0);
    //read from file
    myIStream.getline(buff, buffSize);

    //output what was read to console
    std::cout << buff << std::endl;

    return 0;
}

程序输出:

using my xsputn()
hello world

原因分析

std::istream::getline的默认实现是逐个字符读取,直到遇到换行符或达到指定长度限制。这个过程中,它会反复调用std::basic_streambuf::sbumpc(),而sbumpc()最终会触发underflow()或uflow()来填充缓冲区并获取单个字符——这就是你重载这两个函数能收到通知的原因。

而xsgetn()是用于批量读取多个字符的底层接口,只有当调用std::istream::read()这类明确要求批量读取的成员函数时,才会直接调用xsgetn()。getline并没有使用批量读取逻辑,自然不会触发你重载的xsgetn()。

如果想要让读操作触发xsgetn(),可以把getline替换为read:

myIStream.read(buff, buffSize);

这样就能看到自定义的xsgetn()被调用的输出了。

内容的提问来源于stack exchange,提问作者wigi426

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:25:24