Arhn - архитектура программирования

J2ME nokia s40 исключение из памяти

Я пытаюсь прочитать файл размером 2 МБ в память, а затем отправить этот файл на веб-сервер. Но я получаю исключение из памяти.

         FileConnection fileConn = (FileConnection)Connector.open("file:///" + pictureURI.getString(), Connector.READ);
     InputStream fis = fileConn.openInputStream();
     long overallSize = fileConn.fileSize();

     int chunkSize = 2048;
     int length = 0;
     while (length < overallSize)
     {

        byte[] data = new byte[chunkSize];
        int readAmount = fis.read(data, 0, chunkSize);
        byte[] newImageData = new byte[rawImage.length + chunkSize];
        System.arraycopy(rawImage, 0, newImageData, 0, length);
        System.arraycopy(data, 0, newImageData, length, readAmount);
        rawImage = newImageData;
        length += readAmount;

     }
       fis.close();
        fileConn.close(); 

Загружаются файлы размером 500кб. Что может быть причиной? Пожалуйста, пролейте свет на это.

Я пробовал это также в цикле, но бесполезно, System.gc ();

[EDIT] https://stackoverflow.com/users/45668/malcolm поставил меня на правильном пути. Теперь я ударил сюда

  this.progress = progress;

  HttpConnection conn = null;
  OutputStream os = null;
  InputStream s = null;
  StringBuffer responseString = new StringBuffer();

  try
  {
     System.out.println(System.getProperty("HTTPClient.dontChunkRequests"));
     conn = (HttpConnection)Connector.open(url);
     //conn.setRequestProperty("User-Agent", "Profile/MIDP-2.1 Configuration/CLDC-1.1");
     conn.setRequestMethod(HttpConnection.POST);

     // The messages
     conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------4664151417711");
     conn.setRequestProperty("Content-Length", "355");

     os = conn.openOutputStream();

     System.out.println("file name at upload " + fileName);
     String message1 = "";
     message1 += "-----------------------------4664151417711\r\n";
     message1 += "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n";
     message1 += "Content-Type: image/gif\r\n";
     message1 += "\r\n";

     os.write(message1.getBytes());

     System.gc();

     // Send the image
     int index = 0;
     int size = 2048;
     double progdouble;
     do
     {
        progdouble = ((double)index) / ((double)rawImage.length) * 100;
        progress.setValue((int)progdouble);

        if((index+size) > rawImage.length)
        {
           size = rawImage.length - index;
        }
        os.write(rawImage, index, size);
        index += size;

        System.gc();
     } while(index < rawImage.length);

     String message2 = "\r\n-----------------------------4664151417711\r\n";
     message2 += "Content-Disposition: form-data; name=\"number\"\r\n\r\n";
     message2 += this.user_phone_number;         

     os.write(message2.getBytes());

     String message3 = "\r\n-----------------------------4664151417711\r\n";
     message3 += "Content-Disposition: form-data; name=\"uuid\"\r\n\r\n";
     message3 += this.user_uuid;         

     os.write(message3.getBytes());

     String message4 = "\r\n-----------------------------4664151417711--\r\n";  

     os.write(message4.getBytes());


     os.flush();
     os.close();

     // Read

     s = conn.openInputStream();
     int ch, i = 0, maxSize = 16384;
     while(((ch = s.read())!= -1 ) & (i++ < maxSize)) 
     {
        responseString.append((char) ch);
     }

     conn.close();
     System.out.println("response =>"+responseString.toString());



     return responseString.toString();
  }
  catch (IOException ioe)
  {
     return ioe.toString();
  }

Теперь его провал здесь ..

[EDIT2]

// algorithm that will read 1024 bytes at a time 
        byte b[] = new byte[chunkSize];
        for (int i = 0; i < overallSize; i += chunkSize) { 

            if ((i + chunkSize) < overallSize) {
                fis.read(b, 0, chunkSize);
            } else {
                int left = (int)overallSize - i;
                fis.read(b, 0, left);
            }

            // writing into the output stream - ( these lines will cause the "memory leak", without these, it will not happen)
            os.write(b);
            System.gc(); 

            progdouble = ((double)i) / ((double)overallSize) * 100;
            progress.setValue((int)progdouble); 
        }
        os.flush();

Заранее спасибо.


Ответы:


1

Попутно вы выделяете много новых массивов, что совершенно не нужно. Каждая строка new byte[] выделяет новый массив.

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

FileConnection fileConn;
InputStream is;

try {
    fileConn = (FileConnection) Connector.open("file:///" + pictureURI.getString(), Connector.READ);
    is = fileConn.openInputStream();

    long overallSize = fileConn.fileSize();
    if (overallSize > Integer.MAX_VALUE) throw new IllegalArgumentException("File is too large);
    byte[] imageData = new byte[(int) overallSize];
    int chunkSize = 2048;
    int bytesReadTotal = 0;
    while (bytesRead < overallSize) {
        int bytesRead = is.read(imageData, bytesReadTotal, Math.min(imageData.length - bytesReadTotal, chunkSize));
        if (bytesRead == -1) break;
        bytesReadTotal += bytesRead;
    }
} finally {
    if (is != null) is.close();
    if (fileConn != null) fileConn.close();
}
08.03.2012
  • Спасибо за ответ. Я проверю это и скоро свяжусь с вами. 08.03.2012
  • Вы идете по верному пути. Теперь я могу перейти к чтению файла, но при загрузке получаю ту же ошибку ... Пожалуйста, прочтите этот код. 08.03.2012
  • чтение файлов сейчас в порядке, но когда я пытаюсь загрузить его, я получаю ту же ошибку. Является ли это хорошим методом считывания данных в массив, а затем их очистки или немедленного чтения и отправки - лучший вариант? 09.03.2012
  • @VenuGopalT Если вы хотите только отправить файл, имеет смысл, конечно, не загружать весь файл в память, а вместо этого использовать небольшой буфер. Вы считываете в него часть данных, отправляете ее, а затем повторяете эти шаги, пока не будет отправлен весь файл. 09.03.2012
  • Я пробовал этот метод, но все равно не смог после 60% загрузки. Судя по всему, аппарат (Nokia x2-01) не поддерживает такой размер. Я проверил другие приложения для загрузки видео, в которых есть такая же проблема. 09.03.2012
  • @VenuGopalT Надеюсь, вы не создадите новый массив во время каждой итерации цикла? Описанный мною метод вообще не потребляет память в вашем коде внутри самого цикла. Если он все еще не работает, значит, проблема с реализацией потоков на этой JVM, вы мало что можете сделать в этом случае. 09.03.2012
  • Я не создавал массив в цикле. Для справки я разместил код выше. Пожалуйста, проверьте еще раз, могу ли я что-то сделать? 09.03.2012
  • @VenuGopalT Нет, к сожалению, я так не думаю. Кажется, это что-то внутреннее для JVM. 09.03.2012
  • ОК, нп. Спасибо за поддержку! 09.03.2012

  • 2

    Размер вашего мобильного телефона (Nokia x2-01) ограничен 2 МБ место в куче для всего приложения. Создавайте свое приложение в соответствии с этими ограничениями. 2Мб байтового массива сразу в памяти - никак.

    21.08.2012
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..