gpt4 book ai didi

c++ - 创建 std::iostream 适配器

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:54 25 4
gpt4 key购买 nike

我想创建一个 iostream 适配器类,它允许我即时修改写入流或从流中读取的数据。适配器本身应该是一个 iostream 以允许对第三方代码真正透明。

派生自 std::ostreamStreamEncoder 类示例:

// External algorithm, creates large amounts of log data
int foo(int bar, std::ostream& logOutput);

int main()
{
// The target file
std::ofstream file("logfile.lzma");
// A StreamEncoder compressing the output via LZMA
StreamEncoder lzmaEncoder(file, &encodeLzma);
// A StreamEncoder converting the UTF-8 log data to UTF-16
StreamEncoder utf16Encoder(lzmaEncoder, &utf8ToUtf16);

// Call foo(), but write the log data to an LZMA-compressed UTF-16 file
cout << foo(42, utf16Encoder);
}

据我所知,我需要创建一个新的 basic_streambuf 派生并将其嵌入到 basic_ostream 子类中,但这似乎相当复杂。

有没有更简单的方法来完成这个?

最佳答案

奇怪的是,至少当事情真的打算工作时,这些都不应该直接涉及 iostreams 和/或 streambufs。

我会将 iostream 视为媒人类。 iostream 有一个 streambuf,它为某种外部数据源/接收器提供缓冲接口(interface)。它还具有处理所有格式的语言环境。 iostream 只不过是让这两者很好地一起玩(可以这么说)的 playground supervisor。由于您正在处理数据格式化,因此所有这些都(或应该)在语言环境中处理。

尽管语言环境不是单一的——它由许多 facet 组成,每个 facet 专门用于数据格式化的一个特定部分。在这种情况下,您可能关心的部分是 codecvt 方面,它(几乎专门)用于在从 iostream 读取/写入数据的外部和内部表示之间进行转换。

然而,无论好坏,一个语言环境一次只能包含一个 codecvt facet,而不是像您正在考虑的那样包含它们的链。因此,您真正需要/想要的是一个包装类,它提供一个 codecvt 作为其外部接口(interface),但允许您在 I/O 期间链接一些要对数据完成的任意转换集。

对于 utf 到 utf 的转换,Boost.locale 提供了一个 utf_to_utf 函数和 codecvt 包装器代码,因此这部分转换简单明了。

为了避免有人建议用 ICU 来完成这些事情,我要补充一点,Boost.Locale 几乎是 ICU 的包装器,所以这或多或少是相同的答案,但形式对 C++ 更友好(而 ICU 本身更像 Java,并且几乎完全敌视 C++)。

事情的另一面是编写 codecvt facet 给一个相当简单的任务增加了大量的复杂性。过滤 streambuf(例如)通常很多编写起来更简单。它仍然没有您想要的那么容易,但也没有 codecvt 方面那么糟糕。正如@Flexo 已经提到的,Boost iostreams 库已经包含一个过滤 streambuf,它可以进行 zip 压缩。使用 lzma(或 lzh、算术等压缩)做大致相同的事情相对容易,至少假设你有易于使用的压缩函数(你基本上只是为它们提供输入缓冲区,并且它们提供缓冲区结果)。

关于c++ - 创建 std::iostream 适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11493063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com