Смотря какими средствами пользоваться: через системные вызовы блоками быстрее будет, через библиотечные функции разницы может и не быть (например, библиотека может буферизовать работу с файлами).
Блоками. У тебя есть ещё какие-то варианты? Впрочем, некоторые из них используют обычный потоковый интерфейс. Т.е. fread()/frite(). Но если будешь читать блоками, то лучше использовать read()/write()
грепу для чтения нет никакой разницы, пайп у него на входе или его заставили обычный файл открыть. И что у него там за пайпом (tcp или чей нибудь stdout) ему тоже до определенной степени по барабану.
Обычно так, как ты в последнем посте и написал. читается в буфер, а буфер уже обрабатываешь, как тебе надо. греп и ему подобные читают в буфер, а работают со строками.
Конечно, можно и побайтно считывать, так проще писать, проверок меньше. Если что-то одноразовое надо для себя сляпать, то почему бы и нет... Однако если такое в оренсорц выложить, то сразу в криворукости обвинят и перепишут на другой день.