资源.openRawResource()问题 Android

15

我有一个数据库文件在res/raw/文件夹中。我使用文件名作为R.raw.FileName 调用Resources.openRawResource(),并获得输入流,但是我在设备上有另一个数据库文件,所以为了将该数据库的内容复制到设备上的数据库,我使用:

 BufferedInputStream bi = new BufferedInputStream(is);

我使用FileOutputStream尝试打开一个数据库文件,但是出现了数据库文件损坏的异常。我该如何继续操作呢? 我还尝试使用FileFileInputStream读取文件,路径为/res/raw/fileName,但也不起作用。


有没有人遇到过和我一样的问题,我使用了openFileInput方法,但它检查的是设备路径而不是项目路径... - Sam97305421562
2个回答

38

是的,您应该能够使用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();

0

InputStream.available有严重的限制,不应该用来确定可供流式传输的内容长度。

http://developer.android.com/reference/java/io/FileInputStream.html#available(): "[...]返回可以在没有更多输入的情况下读取或跳过的估计字节数。[...]请注意,此方法提供的保证非常弱,实际上并不是很有用。"

你有三种解决方案:

  1. 两次遍历内容,第一次只计算内容长度,第二次实际读取数据
  2. 由于Android资源是由开发者准备的,因此硬编码其预期长度
  3. 将文件放入/asset目录中,并通过AssetManager读取它,这将使您访问AssetFileDescriptor及其内容长度方法。但是,这可能会为长度提供未知值,这并不是很有用。

嗨,这个现在还有效吗? - elect
@elect API中已经删除了保证提及,但在实践中我仍然建议避免使用该方法。 - TudorT
好的,关于第三个问题,为什么会返回“未知”? - elect

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接