Подтвердить что ты не робот

Прямой доступ к буферизу

Это должно быть довольно распространенным, но я нахожу его увлекательным, что я не нашел прямого решения.

В основном я читаю в файле по сети в строковый поток. Это объявление:

std::stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);

Теперь у меня есть библиотека C, которая хочет прямого доступа к считываемому фрагменту памяти. Как мне это получить? Доступ только для чтения в порядке. После выполнения функции C я избавляюсь от memystream, не нуждаюсь в этом.

str() копирует буфер, который кажется лишним, и удваивает память.

Я пропустил что-то очевидное? Может быть, другой класс stl будет работать лучше.

Edit: По-видимому, строковый поток не гарантируется постоянным сохранением. Что такое?

если я использую vector<char>, как я могу получить буфер байта?

4b9b3361

Ответ 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 или аналогичные придирчивые ссылки и будьте осторожны...