【问题标题】:How do you Deflate data and put it into a vector?你如何压缩数据并将其放入向量中?
【发布时间】:2020-12-28 07:50:50
【问题描述】:

对于zstr, a header-only C++ zlib wrapper library,我正在尝试放气 std::string 并将其放入 std::vector<unsigned char>

zstr::ostream deflating_stream(std::cout);
deflating_stream.write(content.data(), content.size());

上面的代码有效:它打印 Deflate'd。问题是,我不熟悉 C++ 流,也无法将其放入 std::vector。用std::ostringstreamstd::ostreamstd::istringstreamstd::istreambuf_iteratorstd::streambuf.rdbuf() 等等尝试了几次,结果是空的输出(.tellp() == 0)。

我如何放气 std::string 并将其放入 std::vector<unsigned char>


以下是我的一些尝试。我不知道如何访问 Deflate 的数据。

std::istringstream is;
std::ostream ss(is.rdbuf());
zstr::ostream deflating_stream(ss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
the_vector.insert(
    the_vector.cend(),
    std::istreambuf_iterator<char>(is),
    std::istreambuf_iterator<char>()
);
std::ostringstream oss;
zstr::ostream deflating_stream(oss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
const std::string deflated = oss.str();
the_vector.insert(
    the_vector.cend(),
    deflated.cbegin(),
    deflated.cend()
);
std::stringstream ss;
zstr::ostream deflating_stream(ss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
std::string deflated = ss.str();
std::cout << deflated.size(); // Says 0.

【问题讨论】:

  • 我有点密集。您有一个包含压缩数据的 std::string,您希望在 std::vector&lt;unsigned char&gt; 中得到解压缩数据?
  • 如果是这样,那么我认为您将事情复杂化了。只需从您的 zstr 流中读取字节并将字节添加到您的向量中。一个简单的循环,不需要任何花哨的流类。
  • @john,您阅读的内容是正确的。您能否告诉我如何从ostream 或其底层streambuf 读取字节?抱歉,这实际上可能是微不足道的,但这确实是我失败的部分。
  • ostream 使用类似for (char ch; str.get(ch); ) { ... } 的东西。 get 将从输入流中读取单个字符(字节),如果读取失败(有效地)返回 false。
  • 哦,等等,情况正好相反。我正在尝试压缩 std::string未压缩的数据

标签: c++ zlib c++20


【解决方案1】:

这样的工作:

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>

#include "zstr.hpp"

int main() {
  std::string text{"some text\n"};
  std::stringbuf buffer;
  zstr::ostream compressor{&buffer};

  // Must flush to get complete gzip data in buffer
  compressor << text << std::flush;

  // It's probably easier to use just the string...
  auto compstr = buffer.str();
  std::vector<unsigned char> deflated;
  deflated.resize(compstr.size());
  std::copy(compstr.begin(), compstr.end(), deflated.begin());

  std::cout.write(reinterpret_cast<char *>(deflated.data()), deflated.size());
  return 0;
}

编译后:

$ ./a.out | zcat
some text

【讨论】:

  • 谢谢,它就像一个魅力!由于zstr::ostream 构造函数不直接接受std::stringbuf 带有附加选项,因此我使用zstr::ostreambuf 并将其链接到std::ostream:std::stringbuf deflated_data_buffer; zstr::ostreambuf deflating_stream_buffer(&amp;deflated_data_buffer, A_MEBIBYTE_IN_BYTES, Z_BEST_COMPRESSION, 15); std::ostream deflating_stream(&amp;deflating_stream_buffer);。非常感谢你拯救了我的一天。
猜你喜欢
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 2015-07-15
相关资源
最近更新 更多