If using a console text input stream, a ^D on Unix or a ^Z on Windows will indeed result in an EOF for the user program.
With an HD file, there is no such a thing! Because all files are binary on the hard disk. The file system returns "end of file" to the function reading when all bytes (in the intrinsically binary file) on disk are consumed. The file system always calculates EOF based upon number of bytes in the file. There is no ^D or ^Z at the "end of the file". This is needed for a text input stream because there is no limit on the number of bytes (characters).
Using read and a big buffer like 50 MB could be ok on a modern computer. Reading in smaller chunks is fine, but more complicated.