2

I want upload videos from my android apps to server.When iam trying to upload the video my apps shows
04-23 13:07:41.602: ERROR/dalvikvm-heap(519): Out of memory on a 15607356-byte allocation.I dont know why the error is occuring.My question is Can we upload video of size upto 50MB using the below code?if anybody knows please help me...

private void doFileUpload(){
            HttpURLConnection conn = null;
            DataOutputStream dos = null;
            DataInputStream inStream = null;
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary =  "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 8*1024*1024;
            Cursor c = (MainscreenActivity.JEEMAHWDroidDB).query((MainscreenActivity.TABLE_Name), new String[] {
                     (MainscreenActivity.COL_HwdXml)}, null, null, null, null,
                              null);
             if(c.getCount()!=0){
             c.moveToLast();
             for(int i=c.getCount()-1; i>=0; i--) {
                  value=c.getString(0);           
             }
             }
            String urlString = value+"/upload_file.php";
            try
            {
             //------------------ CLIENT REQUEST
                UUID uniqueKey = UUID.randomUUID();
                fname = uniqueKey.toString();
                Log.e("UNIQUE NAME",fname);

            FileInputStream fileInputStream = new FileInputStream(new File(selectedPath) );
            URL url = new URL(urlString);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            dos = new DataOutputStream( conn.getOutputStream() );
             dos.writeBytes(twoHyphens + boundary + lineEnd);
             dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + fname + "."+extension+"" + lineEnd);
             dos.writeBytes(lineEnd);
             bytesAvailable = fileInputStream.available();
             System.out.println("BYTES:--------->"+bytesAvailable);
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             System.out.println("BUFFER SIZE:--------->"+bufferSize);
             buffer = new byte[bufferSize];
             System.out.println("BUFFER:--------->"+buffer);
             bytesRead = fileInputStream.read(buffer,0,bufferSize);
             System.out.println("BYTES READ:--------->"+bytesRead);
             while (bytesRead > 0)
             {
              dos.write(buffer, 0, bufferSize);
              bytesAvailable = fileInputStream.available();
              bufferSize = Math.min(bytesAvailable, maxBufferSize);
              bytesRead = fileInputStream.read(buffer, 0, bufferSize);
              System.out.println("RETURNED");
             }
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

             Log.e("Debug","File is written");
             fileInputStream.close();
             dos.flush();
             dos.close();

            }
            catch (MalformedURLException ex)
            {
                 Log.e("Debug", "error: " + ex.getMessage(), ex);
            }
            catch (IOException ioe)
            {
                 Log.e("Debug", "error: " + ioe.getMessage(), ioe);
            }
            //------------------ read the SERVER RESPONSE
            try {
                  inStream = new DataInputStream ( conn.getInputStream() );
                  String str;

                  while (( str = inStream.readLine()) != null)
                  {
                       Log.e("Debug","Server Response "+str);
                  }
                  inStream.close();

            }
            catch (IOException ioex){
             Log.e("Debug", "error: " + ioex.getMessage(), ioex);
            }
  • i reduced maxBuffersize but iam still getting the same error while uploading.its force closed my activity –  Apr 23 '12 at 09:23
  • my apps upload upto 4.1MB,if i tried to upload more than that my apps get force close..What is the pblm occuring here? I dont have any idea on this.Please help me if anybody knows –  Apr 23 '12 at 12:50

3 Answers3

3

try replacing

 bytesAvailable = fileInputStream.available();
 System.out.println("BYTES:--------->"+bytesAvailable);
 bufferSize = Math.min(bytesAvailable, maxBufferSize);
 System.out.println("BUFFER SIZE:--------->"+bufferSize);
 buffer = new byte[bufferSize];
 System.out.println("BUFFER:--------->"+buffer);
 bytesRead = fileInputStream.read(buffer,0,bufferSize);
 System.out.println("BYTES READ:--------->"+bytesRead);
 while (bytesRead > 0)
 {
  dos.write(buffer, 0, bufferSize);
  bytesAvailable = fileInputStream.available();
  bufferSize = Math.min(bytesAvailable, maxBufferSize);
  bytesRead = fileInputStream.read(buffer, 0, bufferSize);
  System.out.println("RETURNED");
 }

with

buffer = new byte[8192];
bytesRead = 0;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
    dos.write(buf, 0, bytesRead);
}

Explained: read() will return you the number of bytes it read or -1 if the end of the stream is reached and no further data can be read. It also fills the first N bytes of buffer with the data it read. The (a = b) != c syntax first assigns b to a, then compares the value to c (here: execute read, assign result to bytesRead, compare to -1). Therefore the loop runs until every byte is read from start to the end of the stream.

After each read the data in buffer is written via write. Since we know from bytesRead how much bytes in buffer are actually newly read bytes we tell write to write only the bytes from 0 to bytesRead. No need to check InputStream.available() (which may even return meaningless results if the length of the stream is not known) or any other method.

Note: changing that to while (bytesRead > 0) introduces a subtle difference. It will stop reading if you read 0 bytes but did not reach the end of the stream. That case is legal although it is pretty safe to assume that it does not happen. You are safer if you use bytesRead >= 0 though.

zapl
  • 63,179
  • 10
  • 123
  • 154
  • Thank you!! But a little change in while loop "while ((bytesRead = fileInputStream.read(buffer)) > 0) { dos.write(buf, 0, bytesRead); }" –  Apr 24 '12 at 13:34
  • added some explanations, that while loop is pretty much the standard stream copy pattern & you can find it all over the internets. – zapl Apr 24 '12 at 14:48
1

That means, you run out of memory. Try to reduce your my memory usage by decreasing buffer size:

int maxBufferSize = 2*1024*1024;
Caner
  • 57,267
  • 35
  • 174
  • 180
  • can we upload video upto 50MB if we reduce the buffersize? –  Apr 23 '12 at 08:05
  • iam still getting the same error..could you help me to fix the bug? –  Apr 23 '12 at 08:16
  • @sundar buffersize should be more like 8kb (8*1024) - you don't need a giant buffer especially when it's a slow connection. – zapl Apr 24 '12 at 07:55
0

even after using this code you will have same error "out of memory" in this case you should use httppost and multipart entity to post your data...