30921

Resolving java.lang.outofmemory error causing half of the file to be uploaded to server

Question:

I am trying to upload large video files to the server. I wrote a piece of code which works well for the image so I thought I should work it for the video too.

I wrote the below code.

public int uploadFile(String sourceFileUri) { String fileName = sourceFileUri; //Log.v("ONMESSAGE", "File type is " + filetype + "File name is " + fileName); HttpURLConnection conn = null; DataOutputStream dos = null; String lineEnd = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024 * 1024; File sourceFile = new File(sourceFileUri); if (!sourceFile.isFile()) { dialog.dismiss(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "File not found", Toast.LENGTH_LONG).show(); } }); return 0; } else { try { // open a URL connection to the Servlet FileInputStream fileInputStream = new FileInputStream(sourceFile); URL url = new URL("http://example.com/ccs-business/upload.php"); conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("ENCTYPE", "multipart/form-data"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); conn.setRequestProperty("uploaded_file", fileName); dos = new DataOutputStream(conn.getOutputStream()); dos.writeBytes(twoHyphens + boundary + lineEnd); //dos.writeBytes("Content-Disposition: form-data; name="uploaded_file";filename="+ fileName + """ + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName +"\"" + lineEnd); dos.writeBytes(lineEnd); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize);//1 buffer = new byte[bufferSize];//2 bytesRead = fileInputStream.read(buffer, 0, bufferSize); //3 while (bytesRead > 0) { //4 dos.write(buffer, 0, bufferSize);//5 bytesAvailable = fileInputStream.available();//6 bufferSize = Math.min(bytesAvailable, maxBufferSize);//7 bytesRead = fileInputStream.read(buffer, 0, bufferSize);//8 }//9 // send multipart form data necesssary after file data... dos.writeBytes(lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // Responses from the server (code and message) serverResponseCode = conn.getResponseCode(); String serverResponseMessage = conn.getResponseMessage(); Log.i("uploadFile", "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode); if(serverResponseCode == 200){ runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); } fileInputStream.close(); dos.flush(); dos.close(); } catch (MalformedURLException ex) { dialog.dismiss(); ex.printStackTrace(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show(); } }); Log.v("ONMESSAGE", "error: " + ex.getMessage(), ex); } catch (Exception e) { dialog.dismiss(); e.printStackTrace(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show(); } }); Log.v("ONMESSAGE", "Exception : " + e.getMessage(), e); } dialog.dismiss(); return serverResponseCode; } // End else block }

This piece of code gives me <strong>java.lang.OutOfMemory</strong> error so I followed other's suggestion and added a key to manifest that is <strong>largeheap</strong>, did not work. so I followed other suggestion and changed the code to below

public int uploadFileVideo(String sourceFileUri) { String fileName = sourceFileUri; //Log.v("ONMESSAGE", "File type is " + filetype + "File name is " + fileName); HttpURLConnection conn = null; DataOutputStream dos = null; String lineEnd = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1 * 1024 * 1024; File sourceFile = new File(sourceFileUri); if (!sourceFile.isFile()) { dialog.dismiss(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "File not found", Toast.LENGTH_LONG).show(); } }); return 0; } else { try { // open a URL connection to the Servlet FileInputStream fileInputStream = new FileInputStream(sourceFile); URL url = new URL("http://example.com/ccs-business/upload.php"); conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("ENCTYPE", "multipart/form-data"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); conn.setRequestProperty("uploaded_video", fileName); dos = new DataOutputStream(conn.getOutputStream()); dos.writeBytes(twoHyphens + boundary + lineEnd); //dos.writeBytes("Content-Disposition: form-data; name="uploaded_file";filename="+ fileName + """ + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_video\";filename=\"" + fileName +"\"" + lineEnd); dos.writeBytes(lineEnd); bytesAvailable = fileInputStream.available(); /* bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; bytesRead = fileInputStream.read(buffer, 0, bufferSize); */ bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; byte byt[]=new byte[bufferSize]; fileInputStream.read(byt); bytesRead = fileInputStream.read(buffer, 0, bufferSize); dos.write(buffer, 0, bufferSize); // send multipart form data necesssary after file data... dos.writeBytes(lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // Responses from the server (code and message) serverResponseCode = conn.getResponseCode(); String serverResponseMessage = conn.getResponseMessage(); Log.i("uploadFile", "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode); if(serverResponseCode == 200){ runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); } fileInputStream.close(); dos.flush(); dos.close(); } catch (MalformedURLException ex) { dialog.dismiss(); ex.printStackTrace(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show(); } }); Log.v("ONMESSAGE", "error: " + ex.getMessage(), ex); } catch (Exception e) { dialog.dismiss(); e.printStackTrace(); runOnUiThread(new Runnable() { public void run() { Toast.makeText(GcmActivity.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show(); } }); Log.v("ONMESSAGE", "Exception : " + e.getMessage(), e); } dialog.dismiss(); return serverResponseCode; } // End else block }

Now files gets uploaded however all file size of 1 MB and that too can not be played.

Answer1:

bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; byte byt[]=new byte[bufferSize]; fileInputStream.read(byt);

You are not writing the bytes read into byt out to the outputstream. Removing the first read into byt should fix a problem. But you will come across another problem where a file over 1MB only the first 1MB will be uploaded.

A proper way to copy a stream is to do something similar to

byte[] buf = new byte[ 1024 ]; int read = 0; while( ( read = in.read( buf ) ) != -1 ) { out.write( buf, 0, read ); }

Answer2:

avoid buffering the whole POST data in RAM by adding conn.setChunkedStreamingMode(0); after : con.setDoOutput(true); hope this help :)

Recommend

  • broadcast receiver inside activity
  • Android VideoView Quality is so bad on TV Box using Vitamio Library
  • Android RecyclerView Blank Space
  • How to include custom CSS or Javascript on a Content Item in Orchard
  • mfc - MessageBox with rich text
  • bootstrap 3 modal in meteor not showing
  • Unable to retrieve number before incoming call in marshmallow
  • How do I get rid of the Eclipse Find/Replace Bar
  • Create child Window of another process's HWND? (e.g. screensaver preview)
  • IllegalStateException “System services not available to Activities before onCreate()”
  • Access 2007 forms with parameterized RecordSource
  • Powerpoint VBA Macro Save As Dialog File Filter
  • Bootstrap modal closes when dropdownlist inside fires selected index changed event
  • android.app.PendingIntent cannot be accessed ouside the package
  • FCM Data messages are not working properly
  • Returning this from a constructor function in JS
  • dismiss Progress Dialog in another Activity … Android
  • How to remove all of a jQuery UI dialog when it is closed
  • event.getSource() returns null Accessibility in android
  • jersey/tomcat Description The origin server did not find a current representation for the target res
  • Struts 2 TextField Tag with an attribute and no value
  • nonblocking BIO_do_connect blocked when there is no internet connected
  • Assign variable to the value in HTML
  • Visual Studio 2010 debugger build correctly - compiler pdb and linker pdb not in synch?
  • MailKit: The IMAP server replied to the 'EXAMINE' command with a 'BAD' response
  • Alert pop up with LWUIT
  • Sending data from AppleScript to FileMaker records
  • Can I make an Android app that runs a web view in Chrome 39?
  • Display Images one by one with next and previous functionality
  • Circular dependency while pushing http interceptor
  • KeystoneJS: Relationships in Admin UI not updating
  • AngularJs get employee from factory
  • Load html files in TinyMce
  • How to set the response of a form post action to a iframe source?
  • Change div Background jquery
  • LevelDB C iterator
  • Linking SubReports Without LinkChild/LinkMaster
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?