我想使用流下载100MB文件:
我使用AsyncTask类进行下载:
@Override
protected Void doInBackground(String... params) {
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
inputStream = connection.getInputStream();
outputStream = new FileOutputStream(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), params[1]));
byte[] data = new byte[104857600];
int length = inputStream.read(data);
outputStream.write(data, 0, length);
} catch (Exception e) {
Log.e(TAG, "Unable to download file with DownloadTask: " + e.getMessage());
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
connection.disconnect();
} catch (Exception e) {
Log.e(TAG, "Unable to cancel download file with DownloadTask: " + e.getMessage());
}
}
return null;
}
我确定我使用了以下权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
但是当我测试我的应用程序时,它崩溃了,我在logcat Out of memory on a 104857616-byte allocation
中看到了:
10-02 10:28:35.578 29630-2246/com.example.myapp E/dalvikvm-heap: Out of memory on a 104857616-byte allocation.
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:239)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.lang.Thread.run(Thread.java:856)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: Caused by: java.lang.OutOfMemoryError
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at com.example.myapp.DownloaderActivity$DownloadTask.doInBackground(DownloaderActivity.java:126)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at com.example.myapp.DownloaderActivity$DownloadTask.doInBackground(DownloaderActivity.java:107)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:234)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-02 10:28:35.601 29630-2246/com.example.myapp E/AndroidRuntime: at java.lang.Thread.run(Thread.java:856)
有没有办法下载大文件或接受104857600字节(100MB)?
答案 0 :(得分:2)
您已将部分写入数据作为块。系统不会立即为操作提供大量内存。
替换这些行:
byte[] data = new byte[104857600];
int length = inputStream.read(data);
outputStream.write(data, 0, length);
由:
byte [] buffer = new byte[1024];
int bytesRead = 0;
while((bytesRead =input.read(buffer)) != -1) {
outputStream .write(buffer, 0,
bytesRead);
}