无法将 SQLite 数据库从资产文件夹复制到设备内存
Posted
技术标签:
【中文标题】无法将 SQLite 数据库从资产文件夹复制到设备内存【英文标题】:Unable to copy SQLite database from assests folder to device memory 【发布时间】:2011-12-13 09:45:48 【问题描述】:我无法将 SQLite 数据库从评估文件夹复制到设备内存(在模拟器上尝试)。
我的项目的资产文件夹中有一个数据库,其中有一个包含 1000 条预先存在的行的表。
我打算将现有文件从assets文件夹复制到模拟器的数据库文件夹中。
活动片段
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//All views(list,textboxes) are declared.
try
dbM = new DbManager(this);
dbM.checkDataBase();
try
dbM.createDataBase();
catch (Exception e)
throw new Error(" *** ERROR in DB Access *** " + e.getMessage());
dbM.openDB();
symbolarr = dbM.getSymbol();
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, symbolarr));
catch (Exception e)
throw new Error(" *** ERROR in onCreate *** " + e.getMessage());
finally
dbM.close();
我的 DbManager 类中的一段代码:
public boolean checkDataBase()
String myPath = DATABASE_PATH + DATABASE_NAME;
File f = new File(myPath);
return f.exists();
public void createDataBase()
try
InputStream myInput = ctx.getAssets().open(DATABASE_NAME);
OutputStream myOutput = new FileOutputStream(DATABASE_PATH
+ DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
myOutput.write(buffer, 0, length);
myOutput.flush();
myOutput.close();
myInput.close();
catch (FileNotFoundException e)
throw new Error("file not found -- " + e.getMessage());
catch (IOException e)
throw new Error("io exception " + e.getMessage());
catch (Exception e)
throw new Error(" exception " + e.getMessage());
public DbManager openDB() throws SQLException
dbmgr = new DbManager(ctx);
mDb = dbmgr.getWritableDatabase();
return this;
public String[] getSymbol()
Cursor cur;
try
cur = mDb.rawQuery("select symbol,company_name from Scrip", null);
catch (SQLiteException e)
throw new Error(" *** ERROR in cursor *** " + e.getMessage());
String[] b1 = new String[1326];
int x = 0;
if (cur.moveToFirst())
do
b1[x] = cur.getString(cur.getColumnIndex("symbol"));
x++;
while (cur.moveToNext());
cur.close();
return b1;
LOGCAT
FATAL EXCEPTION: main
java.lang.Error: file not found -- AndroidDB.db
at com.dbexample.DbManager.createDataBase(DbManager.java:113)
at com.dbexample.DataAttach.onCreate(DataAttach.java:83)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
at android.app.ActivityThread.access$600(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
注意
1:更改缓冲区大小无济于事..
2:我的资产文件夹中有一个名为 AndroidDB.db 的文件,大小为 62kb。
3:数据库名称(在我的资产文件夹和我的代码中)是相同的,并且我的数据库中有 android_metadata 表,它位于资产文件夹中..
4:当我不使用 createDataBase()
时,正在创建数据库,但没有复制我想要的表,即脚本。所以当我试图从表中获取数据时,我得到了一个异常no such table Scrip
....
这意味着我需要将 Scrip
表从资产文件夹复制到模拟器内存上的数据库。当我尝试使用createDataBase()
做同样的事情时,我得到了 nullPointerException
5.: 当我在 createDatabase() 中尝试以下代码时
AssetManager assetManager = ctx.getAssets();
String[] files = assetManager.list("Files");
for (int i = 0; i < files.length; i++)
str[i] = "\n=" + " file=" + " :" + i + "=" + " name=" + "> "
+ files[i];
Log.v("len=", "" + files.length);
那么 files.length 等于 0
。这只是意味着它无法检测到资产文件夹中的任何文件。
任何帮助都将成为救命稻草!!!
【问题讨论】:
db文件的大小呢?/data/data/com.dbexample/databases/
文件夹中是否有创建文件?
这个大小和asset文件夹里的db文件一样吗?
你可以从here得到它
OMG... 它有效... 感谢一百万吨 这是一个愚蠢的错误。
【参考方案1】:
编辑:用这个替换你的代码,让我知道发生了什么,(这在我的情况下很好用..)
DbManager.java 类:
public class DbManager
private DatabaseHelper dataHelper;
private SQLiteDatabase mDb;
Context ctx;
String DATABASE_PATH = "/data/data/com.demo/databases/";
static String DATABASE_NAME="AndroidDB";
private static final int DATABASE_VERSION = 1;
DbManager(Context ctx)
this.ctx = ctx;
dataHelper = new DatabaseHelper(ctx);
private static class DatabaseHelper extends SQLiteOpenHelper
Context myContext = null;
public DatabaseHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
// TODO Auto-generated constructor stub
@Override
public void onCreate(SQLiteDatabase db)
// TODO Auto-generated method stub
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
// TODO Auto-generated method stub
Log.w("DBHelper", "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data");
onCreate(db);
public boolean checkDataBase()
String myPath = DATABASE_PATH + DATABASE_NAME;
File f = new File(myPath);
return f.exists();
public void createDataBase()
openDB();
try
InputStream myInput = ctx.getAssets().open("AndroidDB.db");
OutputStream myOutput = new FileOutputStream(DATABASE_PATH
+ "AndroidDB");
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
myOutput.write(buffer, 0, length);
if (mDb.isOpen())
mDb.close();
myOutput.flush();
myOutput.close();
myInput.close();
catch (FileNotFoundException e)
throw new Error("file not found -- " + e.getMessage());
catch (IOException e)
throw new Error("io exception " + e.getMessage());
catch (Exception e)
throw new Error(" exception " + e.getMessage());
public DbManager openDB() throws SQLException
mDb = dataHelper.getWritableDatabase();
return this;
public String[] getSymbol()
Cursor cur;
try
cur = mDb.rawQuery("select symbol,company_name from Scrip", null);
catch (SQLiteException e)
throw new Error(" *** ERROR in cursor *** " + e.getMessage());
String[] b1 = new String[1326];
int x = 0;
if (cur.moveToFirst())
do
b1[x] = cur.getString(cur.getColumnIndex("symbol"));
x++;
while (cur.moveToNext());
cur.close();
return b1;
public void close()
try
mDb.close();
catch (Exception e)
e.printStackTrace();
【讨论】:
我已经更新了DATABASE_PATH
到我的 pkg,但仍然是 fileNotFoundException
...
OMG... 它有效... 感谢一百万吨 这是一个愚蠢的错误。【参考方案2】:
检查您添加的数据库名称和错误写入的数据库名称是否相同? (AndroidDB.db) 还要确保您的数据库中有 android_metadata 表。 :)
【讨论】:
两个名称都相同,我的数据库中有 android_metadata 表,位于 assets 文件夹中。 你的代码和我的一模一样,我的代码运行良好。可能是 user370305 的尝试解决方案,他很聪明,解决了我的许多答案:P【参考方案3】:认为您可以从现有数据库中获取路径。那么为什么不让 Android 先创建数据库呢?
在复制您的数据库之前尝试执行“getWritableDb”。然后通过“db.getPath()”获取路径并使用此路径从资产中复制。
这对我有用。
【讨论】:
我主要关心的是copyDatabase
方法。它给了 fileNotFoundException
..以上是关于无法将 SQLite 数据库从资产文件夹复制到设备内存的主要内容,如果未能解决你的问题,请参考以下文章
将 db 从资产复制到设备数据文件夹时出现 FileNotFoundException
将 SQLite 数据库从 sdcard 导入到 android - 没有资产文件夹