2012-03-08 12 views
2

メモリに2MBのファイルを読み込み、そのファイルをWebサーバーに送信しようとしています。しかし、私はメモリ例外が出てきています。J2MEノキアs40メモリ不足例外

  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();

[編集] 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(); 

感謝を打ちました。

答えて

3

途中でたくさんの新しい配列を割り当てますが、これはまったく必要ありません。各new byte[]行は新しい配列を割り当てます。

大規模な配列を読み込む必要があります。ループの前に1回割り当てる必要があります。ファイルの正確なサイズを知っているので、簡単にこれを行うことができます。コードは次のようなものになります。

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(); 
} 
+0

返信いただきありがとうございます。私はこれを確認し、すぐにあなたに戻ってきます。 – Venu

+0

あなたは正しい軌道に乗ります。今、私は読書ファイルから前進することができますが、アップロード中に同じエラーが発生しています... このコードをどうぞご覧ください。 – Venu

+0

ファイルの読み込みは正常ですが、アップロードしようとすると同じエラーが表示されます。配列にデータを読み込んだり、読み込んだり、読み込んだり、即座にプッシュするのが良い方法ですか? – Venu

3

をお使いの携帯電話(Nokia x2-01 specs)は、全体のアプリのためのヒープ領域の2Mバイトに制限されています。これらの制限に従ってアプリケーションを設計します。一度にメモリに2Mバイトのバイナリを書き込むことはできません。