标签: streambuf

basic_streambuf :: seekoff当ios_base :: in |时应该返回什么 是否指定了ios_base :: out?

27.6.3.4.2缓冲区管理和定位

pos_type seekoff(off_type off, ios_base::seekdir way,
    ios_base::openmode which = ios_base::in | ios_base::out);
Run Code Online (Sandbox Code Playgroud)
  • 效果:以一种basic_streambuf为本条款(27.8.2.4,27.9.1.5)中派生的每个类别单独定义的方式改变一个或多个受控序列中的流位置.
  • 默认行为:返回pos_type(off_type(-1)).

到现在为止还挺好.basic_streambuf我正在使用的派生可以单独改变其位置ios_base::in和/或ios_base::out.但是,当指定两者时,我需要返回什么?

如果指定ios_base::in or ios_base::out,我们将返回特定序列的新流位置.

c++ iostream streambuf

8
推荐指数
1
解决办法
287
查看次数

boost :: asio读取从socket到streambuf的n个字节

我有一个序列化的结构,通过套接字发送.我需要以块的形式读取它,因为它的一个字段包含剩余数据的大小:我需要读取前几个字节,找出长度并阅读其余部分.这就是我所拥有的:

    boost::asio::streambuf buffer;
    boost::system::error_code err_code;
    // here I need to read only first 16 bytes
    boost::asio::read(socket, buffer, err_code);
    std::istream is(&buffer);
    boost::archive::binary_iarchive ia(is);
    ia >> my_struct;
Run Code Online (Sandbox Code Playgroud)

我看了看

    boost::asio::async_read(s, boost::asio::buffer(data, size), handler);
Run Code Online (Sandbox Code Playgroud)

但它只能读取数据到boost :: asio :: buffer.我想知道我是否可以使用boost :: asio :: streambuf做同样的事情?先感谢您.

c++ boost streambuf boost-asio boost-serialization

8
推荐指数
1
解决办法
2万
查看次数

"内部"与"关联"流缓冲区之间的区别

来自http://www.cplusplus.com/reference/ios/ios/rdbuf/:

一些派生的流类(例如stringstream和fstream)维护它们自己的内部流缓冲区,它们在构造时与它们相关联.调用此函数来更改关联的流缓冲区应该对该内部流缓冲区没有影响:流将具有与其内部流缓冲区不同的关联流缓冲区(尽管流上的输入/输出操作始终使用关联的流缓冲区,由该成员函数返回).

http://www.cplusplus.com/reference/fstream/ifstream/rdbuf/上:

返回指向内部filebuf对象的指针.

但请注意,这不一定与当前关联的流缓冲区(由ios :: rdbuf返回)相同.

那么如果不用于输入和输出操作,内部缓冲区是什么?如果这意味着这两行可以返回两个不同的对象,为什么这有用呢?

std::stringstream ss;
ss.rdbuf();                          // (1) returns "internal" stream buffer?
static_cast<std::ios&>(ss).rdbuf();  // (2) returns "associated" stream buffer?
Run Code Online (Sandbox Code Playgroud)

c++ iostream streambuf

8
推荐指数
1
解决办法
267
查看次数

二进制版本的iostream

我一直在编写iostreams的二进制版本.它本质上允许您编写二进制文件,但可以很好地控制文件的格式.用法示例:

my_file << binary::u32le << my_int << binary::u16le << my_string;
Run Code Online (Sandbox Code Playgroud)

将my_int写为无符号的32位整数,将my_string写为长度前缀的字符串(前缀为u16le.)要读回文件,可以翻转箭头.效果很好.然而,我在设计上遇到了一个障碍,我仍然围着它.所以,是时候问问了.(我们做了一些假设,例如8位字节,2s补码整数和IEEE浮点数.)

引擎盖下的iostream使用streambufs.这真是一个梦幻般的设计 - iostreams编码' int'到文本的序列化,并让底层的streambuf处理其余的.因此,你得到cout,fstreams,stringstreams等.所有这些,包括iostream和streambufs,都是模板化的,通常是在char上,但有时也是一个wchar.但是,我的数据是一个字节流,最好用' unsigned char' 表示.

我的第一次尝试是基于的模板unsigned char.std::basic_string模板很好,但streambuf没有.我遇到了一个名为class的问题codecvt,我永远无法遵循这个unsigned char主题.这提出了两个问题:

1)为什么streambuf对此类事情负责?似乎代码转换不属于streambuf的职责 - streambufs应该采取流,并缓冲数据到/从它缓冲数据.而已.像代码转换一样高级的东西感觉它应该属于iostreams.

由于我无法使用模板化的streambuf来处理unsigned char,所以我回到char,只是在char/unsigned char之间传递数据.出于显而易见的原因,我试图尽量减少演员阵容.大多数数据基本上都是在read()或write()函数中结束,然后调用底层的streambuf.(并在此过程中使用强制转换.)读取功能基本上是:

size_t read(unsigned char *buffer, size_t size)
{
    size_t ret;
    ret = stream()->sgetn(reinterpret_cast<char *>(buffer), size);
    // deal with ret for return size, eof, errors, etc.
    ...
}
Run Code Online (Sandbox Code Playgroud)

好的解决方案,糟糕的解


前两个问题表明需要更多信息.首先,查看了boost :: serialization等项目,但它们存在于更高级别,因为它们定义了自己的二进制格式.这更适用于较低级别的读/写,其中希望定义格式,或者已经定义了格式,或者不需要或不需要批量元数据.

其次,有些人询问了binary::u32le修饰符.它是一个类的实例化,它具有所需的字节顺序和宽度,此刻可能是未来的签名.该流保存该类的最后传递的实例的副本,并在序列化中使用该副本.这是一个解决方法,我个人试图重载<<运算符:

bostream &operator << (uint8_t n);
bostream &operator << …
Run Code Online (Sandbox Code Playgroud)

c++ binary iostream streambuf

7
推荐指数
1
解决办法
4560
查看次数

Threadsafe日志记录

我想实现一个简单的类来从多个线程进行日志记录.这样的想法是,每个想要记录东西的对象都会收到一个ostream-object,它可以使用通常的操作符来写消息.所需的行为是,在刷新流时将消息添加到日志中.这样,消息不会被来自其他线程的消息中断.我想避免使用临时字符串流来存储消息,因为这会使大多数消息至少是twoliners.正如我所看到的,实现这一目标的标准方法是实现我自己的streambuffer,但这看起来非常麻烦且容易出错.有更简单的方法吗?如果没有,你知道关于自定义streambufs的好文章/指南/指南吗?

提前致谢,

Space_C0wbo0y

更新:

由于它似乎工作,我添加了自己的答案.

c++ logging streambuf

7
推荐指数
2
解决办法
3869
查看次数

使用多个ofstreams在c ++中写入单个输出文件

我上课Writer有两个ofstream成员.
两个流都与同一输出文件相关联.我想在Writer::write方法中使用两个流,但要确保每个流写入实际输出文件的末尾.

class my_ofstream1:
    public ofstream
{
    // implement some functions.
    // using internal, extended type of streambuf
};

class my_ofstream2:
    public ofstream
{
    // implement some functions.
    // using internal, extended type of streambuf 
    // (not the same type as found in my_ofstream1)
};


class Writer
{
public:

    void open(string path)
    {
        f1.open(path.c_str(),ios_base::out); f2.open(path.c_str(),ios_base::out);
    }

    void close()
    {
        f1.close(); f2.close();
    }

    void write()
    {
        string s1 = "some string 1"; …
Run Code Online (Sandbox Code Playgroud)

c++ ofstream streambuf

7
推荐指数
1
解决办法
2776
查看次数

将std :: cout重定向到自定义编写器

我想使用Mr-Edd的iostreams文章中的这个片段在某处打印std :: clog.

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

int main()
{
    std::ostringstream oss;

    // Make clog use the buffer from oss
    std::streambuf *former_buff =
        std::clog.rdbuf(oss.rdbuf());

    std::clog << "This will appear in oss!" << std::flush;

    std::cout << oss.str() << '\\n';

    // Give clog back its previous buffer
    std::clog.rdbuf(former_buff);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以,在一个主循环中,我会做类似的事情

while (! oss.eof())
{
    //add to window text somewhere
}
Run Code Online (Sandbox Code Playgroud)

这是ostringstream文档,但我无法理解这样做的最佳方法.我有一个显示文本的方法,我只想用ostringstream中的任何数据调用它.

将发送到std :: clog的任何内容重定向到我选择的方法的最简单/最好的方法是什么?它是如上所述,并填写while!eof部分(不确定如何),或者是否有更好的方法,比如通过在调用我的方法的地方重载一些'commit'运算符?我喜欢快速简单,我真的不想开始定义接收器,就像文章那样使用boost iostreams - 这些东西已经超出了我的想象.

c++ iostream stream stringstream streambuf

6
推荐指数
3
解决办法
9303
查看次数

如何为自定义istream/streambuf实现seekg()?

十年前,我曾经是一名C++专家,但在过去的十年里,我一直在编写Java.我刚刚开始使用一个小型第三方XML解析器的C++项目.XML解析器接受STL istream.我的XML数据来自Windows COM IStream.我以为我会做正确的事情并创建一个适配器来获取IStream数据并通过istream将它呈现给XML解析器.

我按照http://www.mr-edd.co.uk/blog/beginners_guide_streambuf上的优秀教程创建了一个COMStreambuf,它从底层的COM IStream获取数据,并将其用作自定义COMIstream的缓冲区.一切看起来都不错,但我从解析器中得到一个读错误.

事实证明,解析器通过在istream上使用seekg()来读取整个文件到内存中以查找其大小,然后使用seekg()返回到开头一次读取它.不出所料,前面提到的教程决定"保存[实施寻求的指示]另一篇文章",这显然从未写过.

有人能告诉我我需要做什么来实现我的自定义istream/streambuf的seekg()吗?我会冒险自己做(我的第一个倾向是覆盖istream中的东西),但由于我在STL的深层次和我的Java心态,我担心我会做一些不完整的事情并且有一个脆弱的解决方案.(例如,在没有阅读教程的情况下,我从来没有想过通过编写新的streambuf来制作自定义istream,或者我需要使用默认语言环境调用imbue()等)

谢谢你的帮助.我对这个网站印象非常深刻 - 无论是参与者的知识还是他们友好,诚实的承认谁拥有最佳答案.:)

c++ xml istream streambuf seekg

6
推荐指数
1
解决办法
2239
查看次数

使用boost :: asio :: streambuf的代码会导致段错误

我使用asio :: streambuf遇到了问题,我希望有人可以告诉我,如果我错误地使用了这个类.当我运行这个示例代码时,它会出现段错误.为什么?

为了使事情更加混乱,此代码适用于Windows(Visual Studio 2008),但不适用于Linux(使用gcc 4.4.1).

#include <boost/asio.hpp>
using namespace std;

int main()
{
        boost::asio::streambuf Stream;

        // Put 4 bytes into the streambuf...
        int SetValue = 0xaabbccdd;
        Stream.sputn(reinterpret_cast<const char*>(&SetValue), sizeof(SetValue));

        // Consume 3 of the bytes...
        Stream.consume(3);
        cout << Stream.size() << endl; // should output 1

        // Get the last byte...
        char GetValue;
        // --------- The next line segfaults the program ----------
        Stream.sgetn(reinterpret_cast<char*>(&GetValue), sizeof(GetValue));
        cout << Stream.size() << endl; // should output 0

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ boost streambuf boost-asio

6
推荐指数
1
解决办法
1785
查看次数

如果使用cout.rdbuf()来切换缓冲区并且从不将其设置回来,会出现什么问题?

作者在标题下提出了这段代码A bus error on my platform

#include <fstream>
#include <iostream>

int main()
{
    std::ofstream log("oops.log");
    std::cout.rdbuf(log.rdbuf());
    std::cout << "Oops!\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

字符串"Oops!\n"将打印到文件"oops.log".代码不会恢复cout的streambuf,但VS2010没有报告运行时错误.

c++ fstream streambuf undefined-behavior

6
推荐指数
2
解决办法
962
查看次数