我正在尝试将大文件(~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)
有人可以帮助我吗?