Optimization: only read as many bytes as needed