![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
Soir |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 15.1.2008 Репутация: нет Всего: нет |
Такой вопрос: не знаю почему, но скачивание файла с read(byte b[], 0, length) не выполняется полностью, в то время как вариант с read() (закомментированный блок) работает как надо. Есть подозрения, что прога просто не успевает до конца прочитать файл, но, вроде как, она должна ожидать окончания read(b[] ,0, length). как заставить ее это сделать, если ошибка именно в этом? Если нет, то в чем же ошибка?
проверка программы происходила по следующему url: http://www.coderetard.com/wp-content/uploa...t-msg-thumb.jpg проверял таймаут по адрему - установлен в 0.
|
|||
|
||||
Galaran |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
Присоединяюсь к вопросу.
Попытался сделать с BufferedInputStream
Результат:
Тоже самое Потом попробовал заюзать свой старый велосипед (тоже раньше возникала такая проблема не нашёл как решить, но с малыми объемами данных оно работало)
Читало по-разному - от 10 до 30 кб, но никогда не прочитывало всё. Удивительно, но при отладке всегда(!) читало всё Где подвох? |
||||||
|
|||||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
При чтении данных из интернета нельзя полагаться на то, что сервер всегда сообщает в HTTP заголовке ответа значение Content-Length, т.е. полную длину данных.
Если обьем ответа достаточно большой, то сервер начинает отсылать данные порциями (чанками). В этом случае полная длина ответа серверу неизвестна в момент начала пересылки. Этот режим называется chunked в HTTP 1.1 . При использовании HTTP 1.0 значение Content-Length также может быть неопределено и концом данных является закрытие соединения. Если же значение Content-Length определено, то надо иметь ввиду, что данные пересылаются порциями, с непредсказуемыми паузами. Поэтому универсальным решением является чтение данных до обнаружения их конца. Это сообщение отредактировал(а) COVD - 12.9.2009, 19:15 |
|||
|
||||
Galaran |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
2 варианта. 1й читает побайтово. 2й читает методом read(byte[]) Подправил свой метод чтения с буффером. В обоих случаях заранее неизвестно сколько байт прийдёт. Поэтому в 1м случае я создаю буффер 5МБ, пишу туда, а потом обрезаю полезную часть. Во втором случае я с каждой итерацией создаю новый массив и копирую содержимое предыдущего и добавляю прочитанную порцию.(Не самый оптимальный способ, но рабочий). В итоге должно получиться 2 одинаковых массива. Чтобы это проверить, я вывожу их длину, сравниваю содержимое и, чтобы наверняка - пишу в jpg файл и потом пробую открыть, как картинку.
Код:
В итоге, если запустить, то 1й способ всегда работает, но долго. 2й способ читает только первые 1348 байт
Видно, что на 2й итерации уже приходит количество байт, которое поидее должно прийти в самом конце файла. Куда девается остальная часть файла я не понял Если запустить в режиме отладки и вручную понажимать эти итерации, то всё нормально.
Разве метод read(byte[]) не обеспечивает блокировку до того момента, пока не прийдёт порция данных? В документации сказано: This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. Вот это мне не понятно почему так происходит. Это сообщение отредактировал(а) Galaran - 12.9.2009, 23:25 |
||||||
|
|||||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Обеспечивает. У вас где-то в коде ошибки. Возможно это: есть totalReaded += bufferSize; надо totalReaded += actuallyReaded; |
|||
|
||||
Galaran |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
Буду искать.
не здесь, так как в этом случае количество прочитанных байт всегда равно размеру буффера. |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
В этой строке
переменная actuallyReaded не всегда принимает значение, равное размеру буфера. Значения actuallyReaded могут быть 1 и больше. Не может быть только 0, потому что если данных нет, то чтение блокируется до поступления очередной порции. Как только данные поступают из сети, они копируются в buffer и возвращается количество прочитанных байт. И размер порции теоретически может быть и 1 байт. При обнаружении конца данных read возвращает -1. Это сообщение отредактировал(а) COVD - 14.9.2009, 15:58 |
|||
|
||||
Galaran |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
Воооот оно что...
![]() Спасибо, жаль + не могу поставить А я чего-то там мудрил с проверками буффера ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Работа с сетью | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |