Существуют два способа сделать это.
Сначала вы можете использовать AssetManager.open и, как описано Рохит Нандакумар , и выполнять итерации по входному потоку.
Во-вторых, вы можете использовать AssetManager.openFd , что позволяет использовать FileChannel (который имеет [TransferTo] (https://developer.android.com/reference/java/nio/channels/FileChannel.html#transferTo(long, long, java.nio). Методы .channels.WritableByteChannel)) и [TransferFrom] (https://developer.android.com/reference/java/nio/channels/FileChannel.html#transferFrom(java.nio.channels.ReadableByteChannel, long, long))), поэтому вам не придется самим циклически перебирать входной поток.
Я опишу метод openFd здесь.
Сжатие * +1021 *
Сначала необходимо убедиться, что файл хранится без сжатия. Система упаковки может выбрать сжатие любого файла с расширением, которое не помечено как noCompress , и сжатые файлы не могут быть отображены в памяти, поэтому вам придется полагаться на AssetManager.open в этот случай.
Вы можете добавить расширение «.mp3» к своему файлу, чтобы предотвратить его сжатие, но правильное решение - изменить файл app / build.gradle и добавить следующие строки (чтобы отключить сжатие файлов PDF)
aaptOptions {
noCompress 'pdf'
}
Упаковка файлов
Обратите внимание, что упаковщик все еще может упаковать несколько файлов в один, поэтому вы не можете просто прочитать весь файл, который вам дает AssetManager . Вам нужно спросить AssetFileDescriptor , какие детали вам нужны.
Нахождение правильной части упакованного файла
Убедившись, что ваш файл хранится без сжатия, вы можете использовать метод AssetManager.openFd , чтобы получить AssetFileDescriptor , который можно использовать для получения FileInputStream (в отличие от AssetManager.open , который возвращает InputStream ), который содержит FileChannel . Он также содержит начальное смещение (getStartOffset) и size (getLength) , которое необходимо для получения правильной части файла.
Осуществление
Пример реализации приведен ниже:
private void copyFileFromAssets(String in_filename, File out_file){
Log.d("copyFileFromAssets", "Copying file '"+in_filename+"' to '"+out_file.toString()+"'");
AssetManager assetManager = getApplicationContext().getAssets();
FileChannel in_chan = null, out_chan = null;
try {
AssetFileDescriptor in_afd = assetManager.openFd(in_filename);
FileInputStream in_stream = in_afd.createInputStream();
in_chan = in_stream.getChannel();
Log.d("copyFileFromAssets", "Asset space in file: start = "+in_afd.getStartOffset()+", length = "+in_afd.getLength());
FileOutputStream out_stream = new FileOutputStream(out_file);
out_chan = out_stream.getChannel();
in_chan.transferTo(in_afd.getStartOffset(), in_afd.getLength(), out_chan);
} catch (IOException ioe){
Log.w("copyFileFromAssets", "Failed to copy file '"+in_filename+"' to external storage:"+ioe.toString());
} finally {
try {
if (in_chan != null) {
in_chan.close();
}
if (out_chan != null) {
out_chan.close();
}
} catch (IOException ioe){}
}
}
Этот ответ основан на ответе JPM .