如何将 QByteArray 转换为 std::istream 或 std::ifstream?

Say*_*era 3 c++ qt std istream qbytearray

我想在运行时创建istreamQByteArray而不将物理文件保存在QByteArray.

我发现有很多方法可以进行相反的转换,即istreamQByteArray,但不是这个。

如何做到这一点?

Sch*_*eff 5

std::istringstream通过from读取QByteArray似乎很容易:

\n\n

testQByteArray-istream.cc:

\n\n
#include <iostream>\n#include <sstream>\n#include <QtCore>\n\nint main()\n{\n  qDebug() << "Qt Version:" << QT_VERSION_STR;\n  // make a QByteArray\n  QByteArray data("Hello Qt World.");\n  // convert to std::string\n  std::istringstream in(data.toStdString());\n  // read from istringstream\n  for (;;) {\n    std::string buffer;\n    if (!std::getline(in, buffer)) break;\n    std::cout << "Got: \'" << buffer << "\'\\n";\n  }\n  // done\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

testQByteArray-istream.pro:

\n\n
#include <iostream>\n#include <sstream>\n#include <QtCore>\n\nint main()\n{\n  qDebug() << "Qt Version:" << QT_VERSION_STR;\n  // make a QByteArray\n  QByteArray data("Hello Qt World.");\n  // convert to std::string\n  std::istringstream in(data.toStdString());\n  // read from istringstream\n  for (;;) {\n    std::string buffer;\n    if (!std::getline(in, buffer)) break;\n    std::cout << "Got: \'" << buffer << "\'\\n";\n  }\n  // done\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在cygwin64上编译并测试:

\n\n
SOURCES = testQByteArray-istream.cc\n\nQT = core\n
Run Code Online (Sandbox Code Playgroud)\n\n

完毕。停下来,等等!

\n\n
\n

无需在内存中保存物理文件

\n
\n\n

我不太确定如何阅读此内容。大概就是这样的意思

\n\n

无需复制保存在QByteArray

\n\n

我只看到两个解决方案:

\n\n
    \n
  1. 使用 aQDataStream代替std::stream. 根据医生的说法。QDataStream::QDataStream(const QByteArray &a)

    \n\n
    \n

    构造一个对字节数组 a 进行操作的只读数据流。

    \n
    \n\n

    这听起来很有希望,数据不会被复制。

  2. \n
  3. DIY。创建一个派生类,std::stream可以从该类中读取而QByteArray无需复制。

  4. \n
\n\n

关于 2. 选项,我找到了 Dietmar K\xc3\xbchl\'s 的答案SO: 创建输入流从常量内存。将其应用到上面的示例中,它看起来像这样:

\n\n
#include <iostream>\n#include <QtCore>\n\n// borrowed from /sf/answers/914143681/\nstruct membuf: std::streambuf {\n  membuf(char const* base, size_t size) {\n    char* p(const_cast<char*>(base));\n    this->setg(p, p, p + size);\n  }\n};\nstruct imemstream: virtual membuf, std::istream {\n  imemstream(char const *base, size_t size):\n    membuf(base, size),\n    std::istream(static_cast<std::streambuf*>(this)) {\n  }\n};\n\nint main()\n{\n  qDebug() << "Qt Version:" << QT_VERSION_STR;\n  // make a QByteArray\n  QByteArray data("Hello Qt World.");  \n  imemstream in(data.data(), (size_t)data.size());\n  // read from istringstream\n  for (;;) {\n    std::string buffer;\n    if (!std::getline(in, buffer)) break;\n    std::cout << "Got: \'" << buffer << "\'\\n";\n  }\n  // done\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在cygwin64上再次编译并测试:

\n\n
$ qmake-qt5 testQByteArray-istream.pro\n\n$ make\n\n$ ./testQByteArray-istream \nQt Version: 5.9.4\nGot: \'Hello Qt World.\'\n\n$\n
Run Code Online (Sandbox Code Playgroud)\n