Безопасно ли прыгать назад в ручьях? (std :: ifstream, std :: ofstream) - PullRequest
0 голосов
/ 07 апреля 2020

Случай А. Мне нужно найти что-то в istream, а затем, возможно, перепрыгнуть, чтобы начать сначала.

Случай B. Мне нужно написать в ostream, а затем иногда перепрыгнуть несколько символов, чтобы перезаписать материал. .

Безопасны ли следующие фрагменты кода? (т.е. гарантированно не взломать sh)

// Case A
std::ifstream Stream; // or std::istringstream Stream
// save position
auto initial_position = Stream.tellg();
// Read some characters
while ( ... ) { Stream.get(); ... }
// jump back
Stream.seekg( initial_position );
// Case B
std::ofstream Stream; // or std::ostringstream Stream
// save position
auto initial_position = Stream.tellp();
// Write some characters
while ( ... ) { Stream.put(); ... }
// jump back
Stream.seekp( initial_position );

Примечания:

  1. Я думаю, производительность может пострадать, если мы отскочим назад на позицию, которая имеет уже был «удален из памяти» (для istream) или сброшен на диск (для ostream), но я думаю, что в любом случае это редкий случай. Есть ли способ предотвратить наихудший случай?

  2. Я не хочу (и в основном не могу) использовать промежуточную строку для чтения или записи.

  3. Мой код работал нормально для всего, что я сделал до сих пор, я просто беспокоюсь, что он может сломаться / cra sh при определенных неизвестных обстоятельствах

1 Ответ

2 голосов
/ 07 апреля 2020

Существует причина, по которой он называется потоком - что-то, что вы можете читать или писать только один раз. Как в «Никто никогда не входит в одну и ту же реку дважды, потому что это не одна и та же река, и он не тот же человек». (замените "river" на "stream").

Потоки, поддерживаемые файлами, обеспечивают произвольный доступ, но это скорее исключение. Кроме того, файл может быть обрезан и / или переписан во время чтения, так что вы не сможете искать назад или вперед в потоке файла, который вы только что прочитали.

Самые практичные алгоритмы синтаксического анализа, которые когда-либо изучались каждый байт ввода один раз и последовательно - это делает их пригодными для использования с любым потоком, например, файлом, каналом, сокетом. Возможно, вы захотите реализовать свой синтаксический анализ таким способом.

Существуют другие алгоритмы синтаксического анализа, которые наиболее эффективны, когда они могут искать ввод туда и обратно. Для этих алгоритмов предпочтительным способом является отображение всего файла или указание c его частей в памяти.

...