#c #pipe #seek #fseek
#c #канал #искать #fseek
Вопрос:
Поскольку fseek()
не работает на каналах, какие существуют методы для имитации поиска вперед? Наивный подход заключается в том, чтобы использовать fread()
и выбрасывать содержимое, прочитанное в буфер памяти. Для того, чтобы избежать огромных буферов, вы бы использовали один и тот же буфер снова и снова, при окончательном чтении используя только часть буфера.
Но единственный ли это подход? Есть ли другой способ, который позволяет избежать буфера и потенциального многократного чтения?
Ответ №1:
Поиск не имеет смысла в каналах, потому что входные данные создаются динамически (не сохраняются на диске). lseek
Системный вызов ядра не реализован для каналов.
Также имейте в виду, что канал — это, по сути, буфер производитель-потребитель ограниченного фиксированного размера. Когда он заполняется, производитель приостанавливается до тех пор, пока потребитель не прочитает самые старые данные.
Комментарии:
1. @hippietrail: если есть опасения по поводу буфера и нескольких
read()
вызовов для пропуска данных, возможно, лучше вообще не использовать канал. Пусть исходный код записывается в файл на диске, тогда приемный конец канала может использоватьlseek()
вызовы семейства.2. Конечно, но иногда динамически создаваемый вывод находится в известном формате.
3. @wallyk: Некоторые причины, по которым я использовал каналы в прошлом, включают обработку XML из огромных сжатых архивов и обработку XML «на лету», когда он поступает через Интернет. Иногда то, что вы ищете, требует только части всех данных, иногда у вас нет места на диске, чтобы хранить все такие архивы в несжатом виде.
4. @hippietrail: вот попытка реализовать доступные для поиска каналы в Linux, которая может показаться вам интересной: lkml.indiana.edu/hypermail/linux/kernel/0411.3/0739.html
5. @Blagovest Buyukliev: увы, этот поток завершается без решения.
Ответ №2:
Да, это единственный способ. Я бы использовал буфер где-то около 1-8 кб. При гораздо меньших затратах на чтение будут задействованы служебные данные системного вызова, а при гораздо больших вы удалите полезные данные из кэша.