C ++ Усечение класса iostream - PullRequest
0 голосов
/ 21 января 2012

Для проекта, над которым я работаю над загрузкой / хранением данных в файлах, я принял решение реализовать библиотеку iostream из-за некоторых функций, которые она имеет по сравнению с другими библиотеками io файлов. Одной из таких функций является возможность использовать либо производные классы fstream или stringstream, чтобы разрешить загрузку данных из файла или уже существующего места в памяти. Хотя до сих пор существует один серьезный запасной вариант, и у меня некоторое время возникали проблемы с получением информации об этом.

Подобно функциям, доступным в библиотеке POSIX, я искал некоторую реализацию функций усечения или ftruncate. Для stringstream это будет так же просто, как передать соответствующую строку обратно в поток после восстановления ее с другим размером. На самом деле, для fstream мне еще не удалось найти какой-либо способ сделать это, потому что я даже не могу найти способ вытащить дескриптор файла из этого класса. Хотя дать мне решение проблемы fstream было бы здорово, еще лучшее решение этой проблемы должно быть дружественным к iostream. Поскольку каждое использование любого потокового класса проходит через iostream в моей программе, было бы проще обрезать их через базовый класс, чем выяснять, какой класс управляет потоком каждый раз, когда я хочу изменить общий размер.

В качестве альтернативы, если бы кто-то мог указать мне на библиотеку, которая реализует все эти функции, которые я ищу, и которую легко заменить iostream, это также было бы отличным решением.

Редактировать: Для пояснения, классы iostream, которые я использую, с большей вероятностью будут использовать только классы stringstream и fstream. Реально, только определенный файл должен быть усечен до определенной точки, я просто искал более простой способ справиться с этим, который не требует, чтобы я знал, к какому типу streambuf был присоединен поток. Как и предполагал ответ, я рассмотрю способ использования ftruncate вместе с fstream и просто рассмотрю два конкретных случая, поскольку конечный пользователь моей программы в любом случае не должен видеть потоковые классы.

1 Ответ

0 голосов
/ 21 января 2012

Вы не можете усечь iostream на месте.Вы должны скопировать первые N байтов из существующего потока в новый.Это можно сделать с помощью методов sgetn() и sputn() базового объекта streambuf, которые вы можете получить с помощью iostream::rdbuf().

Однако этот процесс может быть интенсивным вводом / выводом.Может быть лучше использовать особые случаи для манипулирования std::string или вызова ftruncate, как вы упомянули.

Если вы хотите быть действительно агрессивным, вы можете создать собственный std::streambuf Производный класс, который хранит указатель на существующий rdbuf объект в потоке и читает только до определенной точки перед созданием искусственного конца файла.Это будет выглядеть для пользователя как более короткая последовательность ввода / вывода, но на самом деле не освободит память или пространство файловой системы.(Неясно, важно ли это для вас.)

...