Прямой доступ к буферизу
Это должно быть довольно распространенным, но я нахожу его увлекательным, что я не нашел прямого решения.
В основном я читаю в файле по сети в строковый поток. Это объявление:
std::stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);
Теперь у меня есть библиотека C, которая хочет прямого доступа к считываемому фрагменту памяти. Как мне это получить? Доступ только для чтения в порядке. После выполнения функции C я избавляюсь от memystream, не нуждаюсь в этом.
str()
копирует буфер, который кажется лишним, и удваивает память.
Я пропустил что-то очевидное? Может быть, другой класс stl будет работать лучше.
Edit:
По-видимому, строковый поток не гарантируется постоянным сохранением. Что такое?
если я использую vector<char>
, как я могу получить буфер байта?
Ответы
Ответ 1
Вы можете позвонить в str()
, чтобы получить std::string
. Оттуда вы можете позвонить c_str()
на std::string
, чтобы получить char*
. Обратите внимание, что c_str()
официально не поддерживается для этого использования, но все используют его таким образом :)
Изменить
Вероятно, это лучшее решение: std::istream::read
. Из примера на этой странице:
buffer = new char [length];
// read data as a block:
is.read (buffer,length);
Ответ 2
Вы можете полностью управлять буфером, используемым для записи буфера самостоятельно и используя этот буфер в stringstream
stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);
membuf.rdbuf(yourVeryOwnStreamBuf);
Ваш собственный буфер должен быть получен из basic_streambuf
и соответствующим образом переопределить методы sync()
и overflow()
.
Для вашего внутреннего представления вы, вероятно, можете использовать что-то вроде vector< char >
и reserve()
для нужного размера, чтобы не выполнялись перераспределения и копии.
Это означает, что вы знаете верхнюю границу для необходимого пространства. Но если вы заранее не знаете размер и в конце концов нуждаетесь в ограниченном буфере, копии, конечно, неизбежны.
Ответ 3
std::stringstream
не обязательно (обязательно) сохраняет свой буфер смежно, но может выделять куски, поскольку он постепенно заполняется. Если вы хотите, чтобы все данные в смежном регионе памяти были вам нужны, вам нужно будет скопировать его, и это то, что str()
делает для вас.
Конечно, если вы хотите использовать или писать класс с другой стратегией хранения, то вы можете, но вам тогда не нужно использовать std::stringstream
вообще.
Ответ 4
Что ж, если вы серьезно обеспокоены хранением, вы можете стать ближе к металлу. У basic_stringstream есть метод rdbuf(), который возвращает его basic_stringbuf (который получен из basic_streambuf). Затем вы можете использовать указатели eback(), egptr() и gptr() для доступа к символам непосредственно из буфера. В прошлом я использовал этот механизм для реализации собственного буфера с желаемой семантикой, так что это выполнимо.
Осторожно, это не для слабонервных! Отложите несколько дней, прочитайте Стандартные C++ IOStreams и Locales или аналогичные придирчивые ссылки и будьте осторожны...