The CPU can request data from an I/O controller, one byte at a time, but by doing so, it wastes a large chunk of the CPU. Another way of accomplishing the same work without this waste is:
By using an operating system interrupt control.
By using a direct memory access, but only if the hardware has this controller.