2016-04-01 3 views
3

Итак, я создал свой собственный HTTP-сервер на Java с нуля. Пока он работает нормально, но с одним серьезным недостатком. Когда я пытаюсь передать больших файлов в браузер Я получаю Ошибка Java Heap Space. Я знаю, как исправить эту ошибку через JVM, но я ищу долгосрочное решение для этого.JAVA: правильно передать любой файл в браузер

//declare an integer for the byte length of the file 
int length = (int) f.length(); 

//start the fileinput stream. 
FileInputStream fis = new FileInputStream(f); 

//byte array with the length of the file 
byte[] bytes = new byte[length]; 

//write the file until the bytes is empty. 

while ((length = fis.read(bytes)) != -1){ 
    write(bytes, 0, length); 
} 
flush(); 

//close the file input stream 
fis.close(); 

Таким образом, отправляет файл в браузер успешно и потоки это прекрасно но вопрос, потому что я создаю массив с длиной файла. Когда файл очень большой, я получаю ошибку Heap Space.

У меня устранен этот вопрос, используя буфер, как показано ниже, и я больше не получаю ошибки в области кучи. BUT способ, показанный ниже, не правильно передает файлы в браузере. Это как если бы байт файла перетасовывался и отправляется в браузер вместе.

final int bufferSize = 4096; 
byte buffer[] = new byte[bufferSize]; 

FileInputStream  fis = new FileInputStream(f); 
BufferedInputStream bis = new BufferedInputStream(fis); 

    while (true) 
    { 
    int length = bis.read(buffer, 0, bufferSize); 
    if (length < 0) break; 
    write(buffer, 0, length); 
    } 
flush(); 
bis.close(); 
fis.close(); 

NOTE1:

Все правильные заголовки ответа, отправляемые отлично в браузере.

Примечание2:

Оба пути работают отлично на компьютера браузера, но только первый образом работает в браузере смартфона (но иногда это дает мне Heap Space ошибку). Если кто-то знает, как правильно отправлять файлы в браузер и правильно их передавать, я был бы очень счастливым человеком.

Спасибо заранее! :)

+3

Вы, кажется, не отправляете заголовок 'Content-Length', и я тоже не вижу' Content-Type'. Заголовки достаточно важны для HTTP. –

+0

О, я забыл добавить это к моему вопросу. Ответные заголовки отправляются правильно! –

+0

Вы используете сообщества Apache? Если да, тогда вы можете попробовать «IOUtils.copy (inputStream, outputStream);». – nickb

ответ

2

При чтении из BufferedInputStream вы можете позволить его буфер для обработки буферизации, нет никаких оснований прочитайте все в byte[] (и, конечно, не byte[] всего файла). Прочитайте один byte за раз и полагайтесь на внутренний буфер потока. Что-то вроде,

FileInputStream fis = new FileInputStream(f); 
BufferedInputStream bis = new BufferedInputStream(fis); 
int abyte; 
while ((abyte = bis.read()) != -1){ 
    write(abyte); 
} 
+0

это действительно заставляет работать Elliott, спасибо вам большое :) –

0

Эмм ... Как я могу видеть это, вы пытаетесь использовать куски в коде все равно, , как я помню, даже апач HttpClient+FileUpload решение имеет ограничение на размер файла около < = 2.1GB или что-то (исправьте меня, если я ошибаюсь), так что это немного сложно ...

Я еще не пробовал решение, но в качестве теста вы можете использовать java.io.RandomAccessFile в сочетании с файлом (Input/Output) Stream на клиент и сервер, чтобы не читать и писать весь файл за раз, но последовательность позволяет сказать < = 30 МБ блоков, например, чтобы избежать раздражающих ошибок outofmemory; Пример использования RandomAccessFile можно найти здесь https://examples.javacodegeeks.com/core-java/io/randomaccessfile/java-randomaccessfile-example/

Но все же вы даете меньше деталей :(Я имею в виду, что ваш клиент предположительно является распространенным приложением Java или нет?


Если у вас есть дополнительная информация, пожалуйста, дайте мне знать

Удачи :)

Смежные вопросы