Не удается скопировать базу данных SQLite из ресурсов - PullRequest
3 голосов
/ 08 ноября 2011

Я пытаюсь скопировать базу данных 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 result;
    }

    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-карту, и это сработало.Но все еще не могу понять, почему я не могу записать его в папку данных приложения.

Ответы [ 4 ]

7 голосов
/ 08 ноября 2011

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

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 , и что мои базы данных находятся в assets / database /

3 голосов
/ 24 ноября 2012

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

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

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

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

Проблема уже решена.Так удивительно.

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

2 голосов
/ 03 июля 2013
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 голос
/ 10 апреля 2015

Пожалуйста, проверьте папку баз данных перед вашим 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...