J2me multipart / form-data отправка java.lang.exception Ошибка нехватки памяти - требуется помощь

Я пытаюсь отправить изображение из своего мидлета на HTTP-сервер. изображения преобразуются в байты и отправляются на сервер с использованием формата запроса http multipart / form-data.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(boundaryMessage.getBytes());
bos.write(fileBytes);
bos.write(endBoundary.getBytes());

Когда размер изображения меньше примерно 500 КБ, код работает нормально, но когда размер больше, чем он показывает: Неперехваченное исключение java.lang.OutOfMemoryError. Я пробовал использовать Java ME SDK 3.0 и Nokia S40 5th edition FP1. Любая помощь приветствуется. Спасибо, что посмотрели

Я использовал следующий файл класса: щелкните здесь


person ruben    schedule 15.10.2010    source источник
comment
Похоже, что PHP-скрипт на сервере тоже нужно написать. Поскольку оба конца сообщения являются настраиваемым кодом, в какой-то момент отправителю необходимо разделить (фрагментировать) ввод и отправить его по частям. Затем приемнику необходимо собрать файл по частям. Несмотря на то, что используется протокол, состоящий из нескольких частей, здесь он реализуется с нуля. Я думаю, что отправителю необходимо передать параметры, указывающие последовательность частей и общее количество частей при каждой передаче. Итак, отправьте файл как фрагмент 1/5, отправьте фрагмент 2/5 ... и т. Д., Затем напишите PHP, чтобы снова собрать его на сервере.   -  person frayser    schedule 15.10.2010


Ответы (2)


Вынужденное считывание всего файла в память с помощью первого `getFileBytes () для передачи одним фрагментом, скорее всего, является причиной нехватки памяти в системе.

Найдите способ прочитать около 100 КБ, передать его, затем прочитать еще 100, пока не будет готов весь файл.

Конструктор класса HttpMultipartRequest в том виде, в котором он написан, позволяет передавать файл только как один объект. Несмотря на то, что это реализация протокола составного содержимого MIME, он ограничивается случаем передачи только одной части:

Класс можно изменить, чтобы разрешить отправку нескольких частей. Взгляните на спецификацию протокола RFC1341, особенно на промежуточный пример.

С этими тремя строками вместе, как они есть в конструкторе, весь файл отправляется как одна часть;

bos.write(boundaryMessage.getBytes());
bos.write(fileBytes);
bos.write(endBoundary.getBytes());

Но в случае с несколькими частями перед endBoundary должно быть несколько границ:

 for(bytes=getMoreFileBytes(); ! bytes.empty; bytes=getMoreFileBytes()){
        bos.write(boundaryMessage.getBytes());
        bos.write(bytes);
    }
    bos.write(endBoundary.getBytes());

В качестве быстрого исправления позвольте конструктору открыть файл и прочитать его по 100 КБ за раз. Он уже получил параметр fileName.

Сценарий PHP на другом конце должен заново собрать исходный файл из частей.

person frayser    schedule 15.10.2010
comment
Я попытался ответить на ваш комментарий, но он отрицательный, пожалуйста, посмотрите мой ответ ниже - person ruben; 16.10.2010

Я не очень знаком с правилами форума, попробовал прокомментировать ваш ответ, но он отрицательный.

Хорошо .. Теперь я получаю java.io.IOException: постоянное соединение разорвано после отправки первого фрагмента, повторить попытку невозможно.

ранее я пытался использовать тип запроса application / x-www-form-urlencoded с кодировкой Base64, используя код kidcandy здесь: http://forums.sun.com/thread.jspa?threadID=538500

Этот код разделяет данные изображения на куски, чтобы избежать проблемы с постоянным разрывом соединения, и создает соединение с сервером, используя цикл for. Проблема в том, что максимальный размер блока может составлять всего 500-700 байт. Итак, чтобы отправить изображение размером 100 Кб, код должен создать и закрыть соединение 200 раз, я попытался запустить это на телефоне nokia 5310, он ведет себя так, как будто находится в спящем режиме ... так что это бесполезно.

  1. Теперь следует использовать этот цикл for для запроса multipart / form-data?
  2. Каков максимальный размер блока для этого типа запроса?
  3. Или любая другая идея? С Уважением
person ruben    schedule 15.10.2010
comment
Когда я впервые попал в Stack Overflow, я не мог комментировать, можно было только отвечать. Однако вы можете комментировать свои собственные сообщения (верхнюю или эту). Надеюсь, вы сможете решить эту проблему, оставаясь с MIMEMultipart. Я уже получил этот код для выполнения HTTP POST в Apache в моей системе с одного из тех виртуальных телефонов, которые поставлялись с Wireless Tool Набор. Мне потребовалось бы время, чтобы проанализировать этот другой фрагмент кода; кто-то утверждает, что с Apache необходимо отправлять несколько POST вместо одного большого POST с несколькими частями. Возможно, придется добавить эти идеи. - person frayser; 16.10.2010
comment
1. Используйте протокол MIME Multipart content с циклом; см. DataInputStream.read(buffer,offset, length), чтобы читать по 100 КБ за раз. 2. В этом случае максимальная длина данных устанавливается ограничениями памяти. Если 500 КБ - это слишком много, оставьте около 100 КБ. 3. Так как это с нуля, есть, например, еще кое-что, что нужно учесть; после отправки необходимо убедиться, что данные прибыли в неизменном виде (контрольные суммы, ответ OK или FAIL с сервера, повторная передача при ошибке и т. д.). Необходимо написать PHP-скрипт приемника. WebDav или FTP было бы проще; но я не знаю, есть ли хорошая реализация для MID. - person frayser; 16.10.2010
comment
Я использую Apache, и да, думаю, для этого требуется несколько запросов POST вместо большого. Но слишком медленно открывать и закрывать соединение с мобильного устройства так часто. Я подумал, что если бы в протоколе MIME Multipart content размер блока был достаточно большим, например 100 КБ, то для 1 МБ было бы значительно использовать цикл for. Что kidcandy сделал на стороне получателя, так это то, что он последовательно сохранил все данные фрагментов изображения в txt-файле, а затем создал изображение из этих необработанных данных и удалил этот файл на стороне сервера. Напротив, для одного большого составного POST я получил изображение, просто используя переменную $ _FILE []. - person ruben; 16.10.2010
comment
Я страдаю от этой проблемы уже несколько дней ... пожалуйста, дайте мне знать, если вы найдете хорошую реализацию для мидлетов. огромное спасибо - person ruben; 16.10.2010
comment
Насколько я могу судить, Multi-part Content работает с Apache. После изменения, как обсуждалось, этот класс HttpMultipartRequest смог отправить файл по частям, а сценарий PHP получил и воссоздал изображение на другом конце. Хотите протестировать на реальном устройстве? - person frayser; 17.10.2010
comment
Это было здорово, я смог отправить изображение размером 624 КБ. Но когда я попытался отправить 1,3 МБ, ошибка Outofmemory снова вернулась в действие! (SDK Nokia S40 5th edition FP1) Это исходит из того цикла. Я предполагаю, что выходной поток накапливает все изображения в буфере устройства или в памяти кучи (?), Которая переполняется ... дайте мне знать, что вы думаете. - person ruben; 19.10.2010
comment
Еще одна странность заключается в том, что когда я использую J2ME SDK 3.0 и Apache в своей системе, он работает нормально, но когда я помещаю сценарий загрузки на рабочий сервер, он возвращает только пустую строку, размер загруженного файла составляет ‹empty› байтов, ничего не загружено и т. Д. И т. Д. сбит с толку - person ruben; 19.10.2010
comment
Я не заметил кнопку [добавить / показать новые] еще 2 комментария в течение 2 дней. Свяжитесь со мной по электронной почте, см. Ссылку на контактную информацию на главной странице сайта. Я собираюсь взглянуть на это позже. Надеюсь, вы уже пробовали использовать фрагмент меньшего размера; Я полагаю, это было 100 тысяч. - person frayser; 22.10.2010
comment
Обновленный код: это делает read, write и flush в замкнутом цикле, создавая минимальное количество собираемого мусора. Кажется, что при отправке файла размером 1,6 МБ общее использование памяти не превышает 500 КБ. Файл tar также был обновлен; но это полный репозиторий GIT. - person frayser; 24.10.2010