Java, получающая размер большого входного потока, дает нехватку памяти

Я использую этот стандартный фрагмент кода, но он дает нехватку памяти. Пробовал google guava Bytestream.toArray и даже IOUtils.toByteArray, но не повезло. Цель состоит в том, чтобы получить длину входного потока для больших двоичных файлов для дальнейшей обработки входного потока. Также существует ограничение использования файловой системы.

byte[] data = new byte[4096];
while ((nRead = is.read(data, 0, data.length)) != -1) {
    buffer.write(data, 0, nRead);
}

person Gopal    schedule 07.08.2017    source источник
comment
Если вы собираетесь хранить много данных в памяти (что обычно не очень хорошая идея), вам потребуется много памяти. Либо дайте больше памяти JVM, либо придумайте дизайн поумнее.   -  person Kayaman    schedule 07.08.2017
comment
Я ищу этот более умный дизайн :-). Одним из вариантов могло быть сохранение входного потока в файловой системе, но, к сожалению, я не могу использовать этот вариант. У меня есть ограничение, когда мне нужно рассчитать длину входного потока, а затем выполнить определенное действие с этим входным потоком.   -  person Gopal    schedule 07.08.2017
comment
Если ваша единственная цель — найти общий размер, то почему вы храните все это в памяти? Сохраняете ли вы данные, которые записываете, в буфер для последующего использования?   -  person litelite    schedule 07.08.2017
comment
Вам придется лучше объяснить, чего вы пытаетесь достичь.   -  person Kayaman    schedule 07.08.2017
comment
@litelite - в зависимости от длины мне нужно выполнить определенную операцию с входным потоком. Расчет только размера мог бы быть проще.   -  person Gopal    schedule 07.08.2017
comment
@Kayaman - есть большой двоичный файл, который я получаю в качестве входного потока. Я хочу найти размер этого входного потока и выполнить какое-то действие с входным потоком или, скажем, отправить этот входной поток другому API вместе с его размером.   -  person Gopal    schedule 07.08.2017
comment
Если вы не можете прочитать поток дважды (как это обычно бывает), вам просто нужно найти способ хранения байтов. Получите больше памяти, это дешево.   -  person Kayaman    schedule 07.08.2017
comment
Это файл, который вы читаете?   -  person Rabbit Guy    schedule 07.08.2017
comment
@Kayaman - я хотел проверить, есть ли что-то еще, кроме увеличения памяти.   -  person Gopal    schedule 07.08.2017
comment
@rabbitguy - это входной поток, поступающий в составном запросе. Если бы это был файл в какой-то файловой системе, это могло бы быть легко достигнуто, и мое ограничение заключается в том, что я не могу использовать здесь файловую систему.   -  person Gopal    schedule 07.08.2017


Ответы (1)


Если чтение файла невозможно и оно исходит из составного запроса, вы можете попробовать использовать заголовок content-length.

Другой вариант — заставить клиента указать размер файла для файла, чтобы вам не нужно было загружать его в память. Обратите внимание, что это имеет смысл только в том случае, если ваш клиент API является доверенным.

person Danylo Zatorsky    schedule 07.08.2017
comment
заголовок content-disposition также является опцией, как указано в другом сообщении о переполнении стека stackoverflow.com/a/11317380/4374481. - person Palamino; 07.08.2017