无法将资产文件夹中的SQLite数据库复制到设备内存

时间:2011-12-13 09:45:48

标签: android database sqlite fileinputstream fileoutputstream

我无法将SQLite数据库从assests文件夹复制到设备内存(尝试使用模拟器)。

我的项目的assests文件夹中有一个数据库,其中有一个包含1000个预先存在的行的表。

我打算将assets文件夹中的现有文件复制到模拟器的数据库文件夹中。

一块ACTIVITY

     @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表,它位于assets文件夹中。

4:当我不使用 createDataBase() 时,数据库正在获取已创建,但我想要的表ieScrip没有被复制。因此,当我尝试从表中获取数据时,我得到no such table Scrip .... 这意味着我需要将Scrip表从assets文件夹复制到模拟器内存​​中的数据库。当我尝试使用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。这只是意味着它无法检测资产文件夹中的任何文件。

任何帮助都将有益于生命!

3 个答案:

答案 0 :(得分:4)

编辑:用此替换您的代码,让我知道发生了什么,(在我的情况下,这样做很好..)

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

 }

}

答案 1 :(得分:0)

检查添加的数据库名称和错误写入的名称是否相同? (AndroidDB.db) 还要确保在数据库中有android_metadata表。 :)

答案 2 :(得分:0)

认为您可以从现有数据库中获取路径。那么为什么不先要求Android创建数据库呢?

在复制数据库之前尝试执行“getWritableDb”。然后通过“db.getPath()”获取路径,并使用此路径从资产中复制。

这对我有用。