Android 4.4.2导致大型文件上传到Amazon S3失败

时间:2016-09-09 20:43:55

标签: android http amazon-s3 httpurlconnection

我正在尝试将大文件(~200 MB)上传到Amazon S3。我可以使用Android 6(Marshmallow)上传大小为200 MB的大文件,但在使用Android 4.4.2(KitKat)的设备中失败。在使用Android 4.4.2的设备中,我只能上传最大50 MB的文件。对于50 MB以上的文件,它会产生OutOfMemoryError。

代码:

protected Void doInBackground(File... inputs) {

        OutputStream output = null;
        HttpURLConnection connection = null;
        InputStream inputStream = null;

        try {
            file = inputs[0];  // the file path 
            java.util.Date expiration = new java.util.Date();
            long milliSeconds = expiration.getTime();
            milliSeconds += 1000 * 60 * 60; // Add 1 hour.
            expiration.setTime(milliSeconds);


            GeneratePresignedUrlRequest generatePresignedUrlRequest =
                    new GeneratePresignedUrlRequest(Constants.BUCKET_NAME, AppGlobal.deviceId + "/" + file.getName());
            generatePresignedUrlRequest.setMethod(HttpMethod.PUT);

            generatePresignedUrlRequest.setContentType("application/octet-stream");


            generatePresignedUrlRequest.setExpiration(expiration);

            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            bufferSize = 1024*100; //100 k


            final URL url = Util.getS3Client(UploadActivity.this).generatePresignedUrl(generatePresignedUrlRequest);


            String domain = AppGlobal.getDomain(UploadActivity.this);
            int port = Integer.valueOf(AppGlobal.getPort(UploadActivity.this));
            String signature = AppGlobal.getSignature(UploadActivity.this);


            Proxy proxy = new Proxy(Proxy.Type.HTTP,
                    InetSocketAddress.createUnresolved(domain, port));//the proxy server(Can be your laptop ip or company proxy)

            connection = (HttpURLConnection) url.openConnection(proxy);
            connection.setDoOutput(true);


            connection.setRequestMethod("PUT");

            connection.setRequestProperty("Connection", "Keep-Alive");

            connection.setRequestProperty("Content-Type", "application/octet-stream"); 
            // Proxy-Auth header
            String headerVal = String.format("%s:%s", "vzServices", signature);
            byte[] data = headerVal.getBytes("UTF-8");

            connection.addRequestProperty("Proxy-Authorization", "Basic " + Base64.encodeToString(data, Base64.NO_WRAP));

            output = connection.getOutputStream();

            buffer = new byte[bufferSize];
            inputStream = new FileInputStream(file);

            int c = 0;

            int bytes = 0;

            while ((c = inputStream.read(buffer, 0, bufferSize)) > 0) {
                System.out.println("read bytes :" + c);
                output.write(buffer, 0, c);
                bytes+=c;
                System.out.println("write bytes :" + bytes);

            }

            output.flush();
            responseCode = connection.getResponseCode();

            success = true;
            buffer = null;

        } catch (Exception e) {

            e.printStackTrace();
        }
        finally {

            try{
                if(output != null){
                    output.close();
                    output = null;

                }
            }catch (Exception e){

            }
            try{
                if(inputStream != null){
                    inputStream.close();
                    inputStream = null;
                }
            }catch (Exception e){

            }
            try {
                if (connection != null) {
                    connection.disconnect();
                    connection = null;
                }
            }
            catch (Exception e){

            }
        }
        return null;
    }

这是我得到的异常堆栈跟踪:

java.lang.RuntimeException: An error occured while executing doInBackground()
                                                                                      at android.os.AsyncTask$3.done(AsyncTask.java:300)
                                                                                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                                                                                      at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                                                                                      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                                                                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                                                      at java.lang.Thread.run(Thread.java:841)
                                                                                   Caused by: java.lang.OutOfMemoryError
                                                                                      at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
                                                                                      at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
                                                                                      at com.android.okhttp.internal.http.RetryableOutputStream.write(RetryableOutputStream.java:64)
                                                                                      at com.amazonaws.demo.s3transferutility.UploadActivity$UploadTask.doInBackground(UploadActivity.java:613)
                                                                                      at com.amazonaws.demo.s3transferutility.UploadActivity$UploadTask.doInBackground(UploadActivity.java:508)
                                                                                      at android.os.AsyncTask$2.call(AsyncTask.java:288)
                                                                                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                                                                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                                                                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                                                                                      at java.lang.Thread.run(Thread.java:841) 

有人可以帮助我吗?

0 个答案:

没有答案