Как в переносимом C выполнять поиск вперед при чтении из канала

#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 кб. При гораздо меньших затратах на чтение будут задействованы служебные данные системного вызова, а при гораздо больших вы удалите полезные данные из кэша.