Проблемы с ресурсами .openRawResource()
У меня есть файл базы данных в папке res/raw/
. Я вызываю Resources.openRawResource()
с именем файла как R.raw.FileName
, и я получаю поток ввода, но у меня есть другой файл базы данных на устройстве, поэтому для копирования содержимого этого db на устройство db я использую:
BufferedInputStream bi = new BufferedInputStream(is);
и FileOutputStream, но я получаю исключение, что файл базы данных поврежден. Как я могу продолжить?
Я пытаюсь прочитать файл с помощью File
и FileInputStream
, а путь - /res/raw/fileName
, но это также не работает.
Ответы
Ответ 1
Да, вы можете использовать openRawResource
для копирования двоичного файла из папки исходных ресурсов на устройство.
На основе кода примера в демонстрационных версиях API (content/ReadAsset) вы можете использовать вариант следующего фрагмента кода для чтения данных файла db.
InputStream ins = getResources().openRawResource(R.raw.my_db_file);
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
int size = 0;
// Read the entire resource into a local byte buffer.
byte[] buffer = new byte[1024];
while((size=ins.read(buffer,0,1024))>=0){
outputStream.write(buffer,0,size);
}
ins.close();
buffer=outputStream.toByteArray();
Теперь копия вашего файла должна существовать в buffer
, поэтому вы можете использовать FileOutputStream
для сохранения буфера в новый файл.
FileOutputStream fos = new FileOutputStream("mycopy.db");
fos.write(buffer);
fos.close();
Ответ 2
InputStream.available имеет серьезные ограничения и никогда не должен использоваться для определения длины содержимого, доступного для потоковой передачи.
http://developer.android.com/reference/java/io/FileInputStream.html#available():
"[...] Возвращает оценочное количество байтов, которые могут быть прочитаны или пропущены без блокировки для большего ввода. [...] Обратите внимание, что этот метод обеспечивает такую слабую гарантию, что на практике это не очень полезно."
У вас есть 3 решения:
- Просматривайте содержимое дважды, сначала просто для вычисления длины содержимого, во-вторых, чтобы действительно прочитать данные.
- Поскольку ресурсы Android подготовлены вами, разработчик, hardcode его ожидаемая длина
- Поместите файл в каталог /asset и прочитайте его через AssetManager, который даст вам доступ к AssetFileDescriptor и его методам длины содержимого. Однако это может дать вам значение UNKNOWN для длины, что не так полезно.