Sam97305421562
Sam97305421562

Reputation: 3037

Resources.openRawResource() issue Android

I have a database file in res/raw/ folder. I am calling Resources.openRawResource() with the file name as R.raw.FileName and I get an input stream, but I have an another database file in device, so to copy the contents of that db to the device db I use:

 BufferedInputStream bi = new BufferedInputStream(is);

and FileOutputStream, but I get an exception that database file is corrupted. How can I proceed? I try to read the file using File and FileInputStream and the path as /res/raw/fileName, but that also doesn't work.

Upvotes: 15

Views: 59803

Answers (2)

Reto Meier
Reto Meier

Reputation: 96916

Yes, you should be able to use openRawResource to copy a binary across from your raw resource folder to the device.

Based on the example code in the API demos (content/ReadAsset), you should be able to use a variation of the following code snippet to read the db file data.

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();

A copy of your file should now exist in buffer, so you can use a FileOutputStream to save the buffer to a new file.

FileOutputStream fos = new FileOutputStream("mycopy.db");
fos.write(buffer);
fos.close();

Upvotes: 38

TudorT
TudorT

Reputation: 476

InputStream.available has severe limitations and should never be used to determine the length of the content available for streaming.

http://developer.android.com/reference/java/io/FileInputStream.html#available(): "[...]Returns an estimated number of bytes that can be read or skipped without blocking for more input. [...]Note that this method provides such a weak guarantee that it is not very useful in practice."

You have 3 solutions:

  1. Go through the content twice, first just to compute content length, second to actually read the data
  2. Since Android resources are prepared by you, the developer, hardcode its expected length
  3. Put the file in the /asset directory and read it through AssetManager which gives you access to AssetFileDescriptor and its content length methods. This may however give you the UNKNOWN value for length, which isn't that useful.

Upvotes: 0

Related Questions