C++ 如何使用boost将内存中的多个缓冲区压缩为一个缓冲区,并获得其压缩大小?

C++ 如何使用boost将内存中的多个缓冲区压缩为一个缓冲区,并获得其压缩大小?,c++,boost,C++,Boost,我想通过boost的zlib压缩将多个缓冲区(在我的例子中是来自不同来源的视频帧)压缩到一个新的缓冲区中,然后,稍后将所有内容写入磁盘上的文件中。我需要这两个步骤,因为我想在包含压缩缓冲区最终大小的文件中预加一个头(这将在后面用作解析器的偏移量)。我想通过boost的iostreams库实现这一点 出现了以下相关问题: a) 是否需要使用过滤流buf的过滤流?我希望后者已经有了某种缓冲区行为 b) 如何关闭过滤流(buf)并将其写入缓冲区 c) 如何读取压缩数据的最终大小.tellg()未针对这

我想通过boost的zlib压缩将多个缓冲区(在我的例子中是来自不同来源的视频帧)压缩到一个新的缓冲区中,然后,稍后将所有内容写入磁盘上的文件中。我需要这两个步骤,因为我想在包含压缩缓冲区最终大小的文件中预加一个头(这将在后面用作解析器的偏移量)。我想通过boost的iostreams库实现这一点

出现了以下相关问题:

a) 是否需要使用
过滤流buf
过滤流
?我希望后者已经有了某种缓冲区行为

b) 如何关闭
过滤流(buf)
并将其写入缓冲区

c) 如何读取压缩数据的最终大小
.tellg()
未针对这些过滤流实现(如其他地方所述)

d) 您可以有多个源,即我的三个缓冲区,还是需要将它们合并?(我的方法见下文)

类框架{
私人:
/*其他事情*/
公众:
浮动buf1[3];
浮动buf2[3];
浮动buf3[4];
/*更多的东西*/
};
int main(){
框架;
使用boost::iostreams bio;
生物::过滤水;
in.push(bio::gzip_compressor());
/*您是否可以单独添加缓冲区*/
in.push(bio::array_source(reinterpret_cast(frame.buf1),3+7+12+(sizeof(float)*3));
const char*compressed=/*如何关闭并将内容写入此缓冲区*/
int compressedSize=/*如何从in?in.tellg()获取此值不起作用*/
std::stringstream-headerInformation;
人头信息
a) 我需要使用过滤流的过滤流吗?我会的
希望后者已经具有某种缓冲区行为

这两种方法都可以。流添加了文本和区域设置功能,就像在标准库中一样

b) 如何关闭过滤流(buf)并将其写入缓冲区

您可以使用
阵列\u接收器
背面插入器\u设备
、内存映射等。请参阅(“型号”)

c) 如何读取压缩数据的最终大小?.tellg()是 未针对这些过滤流实施(如上所述 其他地方(如此)

从您的底层输出设备/流中检测它。在执行此操作之前,不要忘记刷新/关闭过滤层

d) 您可以有多个来源,即我的三个缓冲区,还是我需要 将它们结合起来?(我的方法见下文)

你可以做你想做的事

放码过来。 我将反转该倡议,并使过滤器在写入输出缓冲区时压缩:

using RawBuffer = std::vector<char>;
using Device = bio::back_insert_device<RawBuffer>;

RawBuffer compressed_buffer; // optionally reserve some size

{
    bio::filtering_ostream filter;
    filter.push(bio::gzip_compressor());
    filter.push(Device{ compressed_buffer });

    filter.write(reinterpret_cast<char const*>(&frame.buf1),
                 sizeof(frame) - offsetof(Frame, buf1));
}
我将把剩下的代码缩减为:

{
    std::ofstream ofs("ouput.data", std::ios::binary | std::ios::app);
    ofs << "START";
    ofs << "END " << compressed_buffer.size();
    ofs.write(compressed_buffer.data(), compressed_buffer.size());
}

添加了完整的内容(总是会出现一些记忆错误的细节:)。感谢您提供的精彩而详尽的答案!这对我绝对有帮助:)
const char *compressed = compressed_buffer.data();
int compressedSize = compressed_buffer.size();
{
    std::ofstream ofs("ouput.data", std::ios::binary | std::ios::app);
    ofs << "START";
    ofs << "END " << compressed_buffer.size();
    ofs.write(compressed_buffer.data(), compressed_buffer.size());
}
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <iterator>
#include <fstream>
#include <vector>
namespace bio = boost::iostreams;

class Frame {
private:
    /* other things */
public:
    float buf1[3];
    float buf2[3];
    float buf3[4];
    /* more things */
};

int main() {
    Frame const frames[]{
        {
            { 1, 2, 3 },
            { 4, 5, 6 },
            { 7, 8, 9, 10 },
        },
        {
            { 11, 12, 13 },
            { 14, 15, 16 },
            { 17, 18, 19, 20 },
        },
        {
            { 21, 22, 23 },
            { 24, 25, 26 },
            { 27, 28, 29, 30 },
        },
    };

    // avoiding UB:
    static_assert(std::is_trivial_v<Frame> &&
                  std::is_standard_layout_v<Frame>);

    using RawBuffer = std::vector<char>;
    using Device = bio::back_insert_device<RawBuffer>;

    std::remove("output.data");
    std::ofstream ofs("output.data", std::ios::binary | std::ios::app);

    RawBuffer compressed_buffer; // optionally reserve some size

    for (Frame const& frame : frames) {
        compressed_buffer.clear(); // do not shrink_to_fit optimizing allocation

        {
            bio::filtering_ostreambuf filter;
            filter.push(bio::gzip_compressor());
            filter.push(Device{ compressed_buffer });

            std::copy_n(reinterpret_cast<char const*>(&frame.buf1),
                        sizeof(frame) - offsetof(Frame, buf1),
                        std::ostreambuf_iterator<char>(&filter));
        }

        ofs << "START";
        ofs << "END " << compressed_buffer.size();
        ofs.write(compressed_buffer.data(), compressed_buffer.size());
    }
}
00000000: 5354 4152 5445 4e44 2035 301f 8b08 0000  STARTEND 50.....
00000010: 0000 0000 ff63 6068 b067 6060 7000 2220  .....c`h.g``p." 
00000020: 6e00 e205 407c 0088 1f00 3183 2303 8300  n...@|....1.#...
00000030: 102b 3802 0058 a049 af28 0000 0053 5441  .+8..X.I.(...STA
00000040: 5254 454e 4420 3438 1f8b 0800 0000 0000  RTEND 48........
00000050: 00ff 6360 3070 6460 7000 e200 204e 00e2  ..c`0pd`p... N..
00000060: 0220 6e00 e20e 209e 00c4 3380 7881 2300  . n... ...3.x.#.
00000070: 763b 7371 2800 0000 5354 4152 5445 4e44  v;sq(...STARTEND
00000080: 2034 391f 8b08 0000 0000 0000 ff63 6058   49..........c`X
00000090: e1c8 c0b0 0188 7700 f101 203e 01c4 1780  ......w... >....
000000a0: f806 103f 00e2 1740 fcc1 1100 dfb4 6cde  ...?...@......l.
000000b0: 2800 0000                                (...