java.nio общеизвестно слишком сложен, если вы все равно собираетесь заблокировать поток.
Было бы намного лучше, если бы вы использовали потоковые службы io и создали метод copyStream, который принимает входной поток и выходной поток.
Если вы говорите о клиентском приложении и хотите отправить данные сервлету, то просто создайте новый поток, чтобы выполнить потоковое копирование, если вы говорите о приложении сервлета и хотите чтобы вернуть этот файл клиенту, тогда вы уже запускаете отдельный поток, и вы можете просто запустить метод copyStream, копирующий файл непосредственно в ServletOutputStream.
Что касается определения, был ли файл загружен или нет, вы можете только сделать предположение. Например, если вы столкнулись с какими-либо ошибками при копировании потока, вы можете с уверенностью предположить, что файл не удался, но если вы не столкнетесь с какими-либо ошибками, вы на самом деле не будете знать, успешно он завершился или нет. Скорее всего, это так, но вы не можете быть уверены.