3

I have to send large files of greater than 10MB to server from an android application. It gives me OutOfMemory exception for large files. I have tried out so many solutions but nothing works. Here is my code which works for small files.

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

        if (!sourceFile.isFile()) {                                    
            Log.e("clusterFileUploaded", fileName);
        }

        try {

            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            URL url = new URL(purl);

            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("clusterFile", fileName); 

            dos = new DataOutputStream(conn.getOutputStream());

            dos.writeBytes(twoHyphens + boundary + lineEnd);         
            dos.writeBytes("Content-Disposition: form-data; name='clusterFile';filename="+ fileName +  lineEnd);

            dos.writeBytes(lineEnd);

            bytesAvailable = fileInputStream.available(); 

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

            bytesRead = fileInputStream.read(buffer, 0, bufferSize);  
            int serverResponseCode = 0;
            while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                dos.flush();
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);   

            }

            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            DataInputStream is = new DataInputStream(conn.getInputStream());

            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();

            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            String sFileResp = sb.toString();

            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();

            Log.i("uploadFile", "HTTP Response is : "
                    + serverResponseMessage + ": " + serverResponseCode+"::"+sFileResp);

            fileInputStream.close();
            dos.flush();
            dos.close();
            return  sFileResp;

        } catch (Exception e) {
            e.printStackTrace();
        }

There are no issues at server end in receiving large files. I don't want to send in chunks. I want to receive whole file at server end.

I am busting my head for so many days but no luck. Any help would be really appreciated.

Bundle of Thanks

Sam
  • 423
  • 2
  • 9
  • 23

2 Answers2

0

Here you can find more about how android manages your app's memory. Android limits the amount of memory that an application can use. This limit varies between devices based on how much RAM the device has. The only way to send large files is to send it in chucks. Here you can find an example: Upload large file in Android without outofmemory error

Hope it helps.

Community
  • 1
  • 1
Akos
  • 82
  • 3
  • This code works by uploading 30MB file to server when I develop a separate app (which only upload file on button click ). However, when this code is placed inside actual app which also does couple of other things then got OOM exception. Can you give your views regarding this behavior – Sam Mar 12 '14 at 09:29
  • That is probably because your actual application already uses a part of the memory that the android OS allows to be used by an application.You should always query your device for the max amount of memory that it allocates for an application and use only maybe 20% of that memory for file upload. – Akos Mar 13 '14 at 09:54
0

add one more method conn.setChunkedStreamingMode(4096)

this ensures that your data is uploaded in chunk size you have defined, also if any of one chunk breaks due to network latency, low battery or due to fluctuating signal strength, only that part of the chunk is uploaded not the whole file.

Note: you can change the size of chunk as i have given 4mb.

Ajay Deepak
  • 471
  • 5
  • 9