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

Поскольку fseek() не работает с каналами, какие методы существуют для имитации поиска вперед? Наивный подход состоит в том, чтобы использовать fread() и выбрасывать считанное содержимое в буфер памяти. Для больших поисков, чтобы избежать огромных буферов, вы должны использовать один и тот же буфер снова и снова с окончательным чтением, используя только часть буфера.

Но единственный ли это подход? Есть ли другой способ избежать буфера и потенциального многократного чтения?


person hippietrail    schedule 27.04.2011    source источник


Ответы (2)


Да, это единственный способ. Я бы использовал буфер где-то около 1k-8k. При гораздо меньшем размере в игру вступают накладные расходы на системный вызов для чтения, а при гораздо большем вы вытесняете полезные данные из кеша.

person R.. GitHub STOP HELPING ICE    schedule 27.04.2011

Поиск не имеет смысла в каналах, потому что ввод создается динамически (не сохраняется на диске). Системный вызов ядра lseek не реализован для каналов.

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

person Blagovest Buyukliev    schedule 27.04.2011
comment
@hippietrail: если есть опасения по поводу буфера и нескольких вызовов read() для пропуска данных, возможно, лучше вообще не использовать канал. Пусть источник записывает в файл на диске, тогда конец канала с приемником может использовать вызовы семейства lseek(). - person wallyk; 27.04.2011
comment
Конечно, но иногда динамически создаваемый вывод имеет известный формат. - person hippietrail; 27.04.2011
comment
@wallyk: Некоторые причины, по которым я использовал каналы в прошлом, включают обработку XML из огромных сжатых архивов и обработку XML «на лету», когда он поступает через Интернет. Иногда то, что вы ищете, требует только часть всех данных, иногда у вас нет места на диске, чтобы хранить все такие архивы в несжатом виде. - person hippietrail; 27.04.2011
comment
@hippietrail: вот попытка реализации поисковых каналов в Linux, которая может показаться вам интересной: lkml.indiana.edu/hypermail/linux/kernel/0411.3/0739.html - person Blagovest Buyukliev; 27.04.2011
comment
@Благовест Буюклиев: увы, эта ветка заканчивается без решения. - person wallyk; 27.04.2011
comment
@hippietrail: Тогда единственное разумное решение - самостоятельно повторно реализовать исходный конец канала таким образом, чтобы это было полезно для ваших целей. - person wallyk; 27.04.2011