Excellent example. I thought of a read loop and the priming read also.
Of course, moving your read to a subprocedure that returns a Boolean helps
cut that out.
// process read
And, as you've said, it is a balance on which principle to apply.