Чтение через std::istringstream
из QByteArray
кажется довольно простым:
testQByteArray-istream.cc
:
#include <iostream>
#include <sstream>
#include <QtCore>
int main()
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
// make a QByteArray
QByteArray data("Hello Qt World.");
// convert to std::string
std::istringstream in(data.toStdString());
// read from istringstream
for (;;) {
std::string buffer;
if (!std::getline(in, buffer)) break;
std::cout << "Got: '" << buffer << "'\n";
}
// done
return 0;
}
testQByteArray-istream.pro
:
SOURCES = testQByteArray-istream.cc
QT = core
Скомпилированои протестировано на cygwin64 :
$ qmake-qt5 testQByteArray-istream.pro
$ make
$ ./testQByteArray-istream
Qt Version: 5.9.4
Got: 'Hello Qt World.'
$
Готово.Стоп, подождите!
без сохранения физического файла в памяти
Я не совсем уверен, как это прочитать.Вероятно, это означает
без копирования данных, сохраненных в QByteArray
Я вижу только два решения:
ИспользованиеQDataStream
вместо std::stream
.Согласно док.QDataStream::QDataStream(const QByteArray &a)
Создает поток данных только для чтения, который работает с байтовым массивом a.
Звучит очень обещая, что данные не копируются.
DIY.Создайте класс, полученный из std::stream
, который может читать из QByteArray
без копирования.
Относительно 2. Я нашел ответ Дитмара Кюля на SO: Создание вводапоток из постоянной памяти .Если применить это к приведенному выше примеру, это будет выглядеть так:
#include <iostream>
#include <QtCore>
// borrowed from https://stackoverflow.com/a/13059195/7478597
struct membuf: std::streambuf {
membuf(char const* base, size_t size) {
char* p(const_cast<char*>(base));
this->setg(p, p, p + size);
}
};
struct imemstream: virtual membuf, std::istream {
imemstream(char const *base, size_t size):
membuf(base, size),
std::istream(static_cast<std::streambuf*>(this)) {
}
};
int main()
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
// make a QByteArray
QByteArray data("Hello Qt World.");
imemstream in(data.data(), (size_t)data.size());
// read from istringstream
for (;;) {
std::string buffer;
if (!std::getline(in, buffer)) break;
std::cout << "Got: '" << buffer << "'\n";
}
// done
return 0;
}
Скомпилировано и протестировано снова на cygwin64 :
$ qmake-qt5 testQByteArray-istream.pro
$ make
$ ./testQByteArray-istream
Qt Version: 5.9.4
Got: 'Hello Qt World.'
$