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