Great ideas here, Stephen. And the same general line of reasoning certainly could be modified in many ways. For example, one could pre-read and then buffer a few lines from each file, replenishing each buffer on an as-needed basis as the program proceeds. This would give fairly efficient access to “the next few lines in each file” without too much burden, and it would scale. You could introduce the concept of “bookmarking” your present position in any given file, then “reading ahead” in search of what you are looking for, knowing that you can “fall back” to the bookmarked point. And so on. All of which wizardry can be generally concealed from most of the rest of the programming.
There are definite limits on the number of file-handles that an operating system can be expected to allow any application to have open at one time, and those limits are often rather small ... in theory and/or in practice. I tend to design on the assumption of “maybe, a few dozen.”