Reputation: 1229
I am trying to copy a file of about 80 megabytes from the assets folder of an Android application to the SD card.
The file is another apk. For various reasons I have to do it this way and can't simply link to an online apk or put it on the Android market.
The application works fine with smaller apks but for this large one I am getting an out of memory error.
I'm not sure exactly how this works but I am assuming that here I am trying to write the full 80 megabytes to memory.
try {
int length = 0;
newFile.createNewFile();
InputStream inputStream = ctx.getAssets().open(
"myBigFile.apk");
FileOutputStream fOutputStream = new FileOutputStream(
newFile);
byte[] buffer = new byte[inputStream.available()];
while ((length = inputStream.read(buffer)) > 0) {
fOutputStream.write(buffer, 0, length);
}
fOutputStream.flush();
fOutputStream.close();
inputStream.close();
} catch (Exception ex) {
if (ODP_App.getInstance().isInDebugMode())
Log.e(TAG, ex.toString());
}
I found this interesting - A question about an out of memory issue with Bitmaps
Unless I've misunderstood, in the case of Bitmaps, there appears to be some way to split the stream to reduce memory usage using BitmapFactory.Options.
Is this do-able in my scenario or is there any other possible solution?
Upvotes: 1
Views: 1779
Reputation: 16152
Do not read the whole file into memory; read 64k at a time, then write them, repeat until you reach the end of file. Or use IOUtils from Apache Commons IO.
Upvotes: 2
Reputation: 57326
The trick is not to try to read the whole file in one go, but rather read it in small chunks and write each chunk before reading the next one into the same memory segment. The following version will read it in 1K chunks. It's for example only - you need to determine the right chunk size.
try {
int length = 0;
newFile.createNewFile();
InputStream inputStream = ctx.getAssets().open(
"myBigFile.apk");
FileOutputStream fOutputStream = new FileOutputStream(
newFile);
//note the following line
byte[] buffer = new byte[1024];
while ((length = inputStream.read(buffer)) > 0) {
fOutputStream.write(buffer, 0, length);
}
fOutputStream.flush();
fOutputStream.close();
inputStream.close();
} catch (Exception ex) {
if (ODP_App.getInstance().isInDebugMode())
Log.e(TAG, ex.toString());
}
Upvotes: 7