Было бы неразумно открывать файл на стороне клиента, читать все его содержимое в память, закрывать его и затем начинать отправку содержимого именно потому, что содержимое может превышать доступную память.
Один из вариантов - открыть файл, прочитать его фрагмент (конечно же, помня, где закончился последний блок), закрыть файл, загрузить его на сервер и собрать файл на стороне сервера, добавив предыдущие фрагменты. Это не тривиальная процедура, и она должна учитывать такие вещи, как управление ресурсами, ошибки ввода-вывода и синхронизация, особенно при работе параллельно с несколькими потоками.