Лучший способ определить длину std :: istream? - PullRequest
7 голосов
/ 27 октября 2009

Есть ли лучший способ определить длину std :: istream, чем следующий:

std::istream* pcStream = GetSomeStream();
pcStream->seekg(0, ios::end);
unsigned int uiLength = pcStream->tellg();

Просто кажется действительно расточительным искать конец потока и затем возвращаться к исходному положению, особенно если поток может быть файлом на медленном носителе, таком как CD или DVD.

Ответы [ 4 ]

7 голосов
/ 27 октября 2009

«Лучший» способ - избегать необходимости длины:)

  • Не все потоки доступны для поиска (например, представьте istream в сетевом сокете)
  • Тип возвращаемого значения от tellg () не обязательно является числовым (единственное требование - его можно передать обратно в seekg () для возврата в ту же позицию)
  • Даже если он числовой, это не обязательно число байтов. Например, это может быть «магическое» значение, означающее «в конце»
  • Для fstream такие проблемы, как преобразование регистра и перевода строки, могут испортить ситуацию
1 голос
/ 05 января 2019

Чтобы получить текущую длину / размер пара, я делаю это:

auto size = strlen(currentStream.str().c_str());

Это должно произойти до того, как функции установят его размер на 0, например move(currentStream).

0 голосов
/ 07 июля 2015

Был какой-то поток, который не мог получить длину, вызывая tellg(). В случае tellg() может вернуть -1.

Вы можете получить длину потока, подготовив буфер достаточного размера. Я узнал, как получить длину, изучив функцию stream::read.

const int DATA_SIZE = 1024 * 512;
char buf[DATA_SIZE];  // 1024 * 512 is enough!
std::istream& is = GetSomeStream();
int Len = is.rdbuf()->sgetn(buf, DATA_SIZE);

Выше Len - реальный размер данных в istream.

0 голосов
/ 27 октября 2009

Рассматривали ли вы отслеживать размер с помощью istream :: gcount ()?

...