Не удается скопировать базу данных SQLite из ресурсов

#java #android #sqlite

#java #Android #sqlite

Вопрос:

Я пытаюсь скопировать базу данных SQLite из каталога ресурсов, чтобы получить к ней доступ позже. Но я не могу этого сделать!

 public class DatabaseAdapter {
    private static String DB_PATH = "/data/data/com.mypackage/databases/";
    private static String DB_NAME = "database.sqlite";
    private static String TABLE_NAME = "content_table";

    private SQLiteDatabase database = null;
    private final Context context;

    public DatabaseAdapter(Context context){
        this.context = context;
    }

    private void openDatabase() throws SQLiteException{
        DatabaseHelper databaseHelper = new DatabaseHelper(context, DB_NAME);
        SQLiteDatabase db = null;
        if(!checkDatabase()){
            try{
                //Tried to create db before copying, so file should exist
                db = databaseHelper.getReadableDatabase();
                db.close();

                copyDatabase();

            }catch(IOException exception){
                Log.d("DatabaseAdapter", "Error copying DB: " exception);
            }
        }

        database = SQLiteDatabase.openDatabase(DB_PATH DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
    }

    private void closeDatabase(){
        database.close();
    }

    public ArrayList<String> queryCategories(){
        try{
            openDatabase();
        }catch(SQLiteException exc){
            exc.printStackTrace();
        }
        //.............................
        return resu<
    }

    private boolean checkDatabase(){
        File dbFile = new File(DB_PATH   DB_NAME);
        return dbFile.exists();
    }

    private void copyDatabase() throws IOException{
        InputStream inputStream = context.getAssets().open(DB_NAME);

        String outFileName = DB_PATH   DB_NAME;

        OutputStream outputStream = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer))>0){
            outputStream.write(buffer, 0, length);
        }

        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }

}
  

DatabaseHelper прост:

 ublic class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context, String name){
        super(context, name, null, 1);

    }


    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}
  

Перепробовал все! Я пытался поиграть с расширением! Но я все еще получаю сообщение об ошибке:
Ошибка копирования базы данных: java.io.FileNotFoundException: /data/data/com.mypackage/databases/database.sqlite (No such file or directory)

Я проверил на эмуляторе, мой файл там, так что я должен иметь возможность записывать в него! Пожалуйста, любая помощь! Это сводит меня с ума!

UPD Я попытался поместить ее на SD-карту, и это сработало. Но все еще не могу понять, почему я не могу записать это в папку данных приложения.

Ответ №1:

Я использую этот помощник и работает нормально:

 public class DBHelper extends SQLiteOpenHelper{

private final static String DB_PATH = "/data/data/[YOUR PACKAGE HERE]/databases/";

String dbName;
Context context;

File dbFile;

public DBHelper(Context context, String dbName, CursorFactory factory,
        int version) {
    super(context, dbName, factory, version);
    this.context = context;
    this.dbName = dbName;
    dbFile= new File(DB_PATH   dbName);
}

@Override
public synchronized SQLiteDatabase getWritableDatabase() {

    if(!dbFile.exists()){
        SQLiteDatabase db = super.getWritableDatabase();
        copyDataBase(db.getPath());
    }
    return super.getWritableDatabase();
}

@Override
public synchronized SQLiteDatabase getReadableDatabase() {
    if(!dbFile.exists()){
        SQLiteDatabase db = super.getReadableDatabase();
        copyDataBase(db.getPath());
    }
    return super.getReadableDatabase();
}

@Override
public void onCreate(SQLiteDatabase db) {}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

private void copyDataBase(String dbPath){
    try{
        InputStream assestDB = context.getAssets().open("databases/" dbName);

        OutputStream appDB = new FileOutputStream(dbPath,false);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = assestDB.read(buffer)) > 0) {
            appDB.write(buffer, 0, length);
        }

        appDB.flush();
        appDB.close();
        assestDB.close();
    }catch(IOException e){
        e.printStackTrace();
    }

}

}
  

Примите во внимание, что расширение файла базы данных — .db и что мои базы данных находятся в ресурсах / databases /

Комментарии:

1. как я могу добавить запись в скопированную базу данных?

Ответ №2:

У меня такая же проблема, и я исправил ее с помощью другого подхода. В начале я объявил путь к базе данных, как это делали все:

 dbPath="data/data/<my package name>/databases/data.db"
  

Это точный путь, ошибки нет. Но это всегда приводит к сбою, когда я пытаюсь открыть OutPutFileStream для копирования базы данных. Я не знаю почему. И затем я изменяю способ открытия базы данных, как показано ниже:

 dbPath = context.getDatabasePath(dbName);
OutputStream myOutput = new FileOutputStream(dbPath.getAbsolutePath());
  

Проблема решена. Итак, сюрприз.

Надеюсь, это поможет.

Ответ №3:

 public static void copyDatabase(final Context ctx, String dbName) {
    if (ctx != null) {
        File f = ctx.getDatabasePath(dbName);
        if (!f.exists()) {

            // check databases exists
            if (!f.getParentFile().exists())
                f.getParentFile().mkdir();

            try {
                InputStream in = ctx.getAssets().open(dbName);
                OutputStream out = new FileOutputStream(f.getAbsolutePath());

                byte[] buffer = new byte[1024];
                int length;
                while ((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
                in.close();
                out.close();
                Logger.i("Database copy successed! "   f.getPath());
            } catch (Exception ex) {
                Logger.e(ex);
            }
        }
    }
}
  

Комментарии:

1. Вам следует добавить несколько комментариев.

Ответ №4:

Пожалуйста, проверьте папку databases перед вашим OutputStream.

вот так,

 File databaseFile = new File(context.getFilesDir().getAbsolutePath()
            .replace("files", "databases"));

// check if databases folder exists, if not create it.
if (!databaseFile.exists()){
    databaseFile.mkdir();
}