2014-01-21 2 views
-3

Я создаю приложение Dictionary, которое использует существующую базу данных sqlite. Я поместил свою базу данных в папку с ресурсами, и я использую следующий код для копирования базы данных, когда приложение запускается в первый раз. (Я позаимствовал идею из this поста)Скопировать базу данных из папки с данными

DatabaseHelper.java

public class DatabaseHelper { 

private static String DB_PATH = ""; 
private static String DB_NAME = "abc.sqlite"; 
private SQLiteDatabase myDatabase; 
private Context myContext; 

public DatabaseHelper(Context context) { 

    myContext = context; 

    if (android.os.Build.VERSION.SDK_INT >= 17) 
     DB_PATH = context.getApplicationInfo().dataDir + "/databases/"; 
    else 
     DB_PATH = "/data/data/" + context.getPackageName() + "/databases/"; 
    Log.d("path", DB_PATH); 
} 

public void copyDatabase() { 

     InputStream myInput; 
     OutputStream outStream; 
     try { 
      myInput = myContext.getAssets().open(DB_NAME); 
      String file = DB_PATH + DB_NAME; 
      outStream = new FileOutputStream(file); 

      byte[] buffer = new byte[1024]; 
      int length = 0; 
      while ((length = myInput.read(buffer)) >= 0) { 
       outStream.write(buffer, 0, length);    
      } 
      outStream.flush(); 
      myInput.close(); 
      outStream.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

И тогда я называю выше copyDatabase() метод формирования моего MainActivity. Вот код.

public class MainActivity extends Activity { 
    DatabaseHelper myDbHelper; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.layout); 
     myDbHelper = new DatabaseHelper(getApplicationContext()); 
     myDbHelper.copyDatabase(); 


    } 

} 

Но проблема в том, что Android не копирует базу данных. Я использовал инструмент «Журнал», и выяснил, что цикл while никогда не запускается. В чем проблема в этом коде. Спасибо.

+0

Просто измените строку цикла while как while ((length = myInput.read (buffer))> 0) {'просто сравните его с'> 'not'> = '. – GrIsHu

+0

Ya Продолжайте работу с GrlsHu, и вам необходимо создать файл перед Goo FileOutputStream, а также –

+2

Есть десяток примеров этого на SO и в других местах. Должен иметь googled. – 323go

ответ

2

Измените ваш цикл в то время, как показано ниже:

Кроме того, ваше состояние >= больше чем или равным, чтобы изменить его только на > Больше

while ((length = myInput.read(buffer)) > 0) { 
      outStream.write(buffer, 0, length);    
     } 

Попробуйте приведенный ниже код, который будет работать для вас, как шарм.

public class DataBaseHelper extends SQLiteOpenHelper { 
    private Context mycontext; 
    private String DB_PATH; 

    private static String DB_NAME = "abc.sqlite"; 
    public SQLiteDatabase myDataBase; 


    public DataBaseHelper(Context context) throws IOException { 
     super(context,DB_NAME,null,1); 
     this.mycontext=context; 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
       opendatabase(); 
     } else { 
      System.out.println("Database doesn't exist"); 
      createdatabase(); 
     } 
    } 

    public void createdatabase() throws IOException { 
     boolean dbexist = checkdatabase(); 
     if(!dbexist) { 
      this.getReadableDatabase(); 
      try { 
       copydatabase(); 
      } catch(IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 

    private boolean checkdatabase() { 

     boolean checkdb = false; 
     try { 
      String myPath = DB_PATH + DB_NAME; 
      File dbfile = new File(myPath); 
      checkdb = dbfile.exists(); 
     } catch(SQLiteException e) { 
      System.out.println("Database doesn't exist"); 
     } 
     return checkdb; 
    } 

    private void copydatabase() throws IOException { 
     //Open your local db as the input stream 
     InputStream myinput = mycontext.getAssets().open(DB_NAME); 

     // Path to the just created empty db 
     String outfilename = DB_PATH + DB_NAME; 

     //Open the empty db as the output stream 
     OutputStream myoutput = new FileOutputStream(outfilename); 

     // transfer byte to inputfile to outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myinput.read(buffer))>0) { 
      myoutput.write(buffer,0,length); 
     } 

     //Close the streams 
     myoutput.flush(); 
     myoutput.close(); 
     myinput.close(); 
    } 

    public void opendatabase() throws SQLException { 
     //Open the database 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE); 
    } 

    public synchronized void close() { 
     if(myDataBase != null) { 
      myDataBase.close(); 
     } 
     super.close(); 
    } 

} 

В вашей MainActivity просто нужно создать и экземпляр вашего DatabaseHelper класса другим будет управлять на это самостоятельно.

public class MainActivity extends Activity { 
    DatabaseHelper myDbHelper; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.layout); 
     myDbHelper = new DatabaseHelper(MainActivity.this); 
     } 

} 
+0

Эй, спасибо за ваш ответ. Но код все еще не работает. – Rajat

+0

@ Rajat Вы пробовали отлаживать свой код? Показывать, где вы вызываете метод 'copyDatabase'? – GrIsHu

+0

Я добавил код MainActivity.java. Пожалуйста, проверьте. Спасибо – Rajat

0

Используется этот код для копирования базы данных из папки активов

public class DataBaseHelper extends SQLiteOpenHelper 
{ 
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window 
//destination path (location) of our database on device 
private static String DB_PATH = ""; 
//private static String DB_NAME ="(students).sqlite";// Database name 
private static String DB_NAME ="virtualDB"; 
private SQLiteDatabase mDataBase; 
private final Context mContext; 

public DataBaseHelper(Context context) 
{ 
    super(context, DB_NAME, null, 1);// 1? its Database Version 
    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/"; 
    Log.i(TAG, DB_PATH); 
    this.mContext = context; 
}  

public void createDataBase() 
{ 
    //If database not exists copy it from the assets 

    boolean mDataBaseExist = checkDataBase(); 
    if(!mDataBaseExist) 
    { 
     this.getReadableDatabase(); 
     this.close(); 
     try 
     { 
      //Copy the database from assests 
      copyDataBase(); 
      Log.e(TAG, "createDatabase database created"); 
     } 
     catch (IOException mIOException) 
     { 
      Log.i(TAG, "createDataBase "+mIOException+""); 
     } 
    } 
} 
    //Check that the database exists here: /data/data/your package/databases/Da Name 
    private boolean checkDataBase() 
    { 
     File dbFile = new File(DB_PATH + DB_NAME); 
     //Log.v("dbFile", dbFile + " "+ dbFile.exists()); 
     return dbFile.exists(); 
    } 

    //Copy the database from assets 
    private void copyDataBase() throws IOException 
    { try 
    { 
     InputStream mInput = mContext.getAssets().open(DB_NAME); 
     String outFileName = DB_PATH + DB_NAME; 
     OutputStream mOutput = new FileOutputStream(outFileName); 
     byte[] mBuffer = new byte[1024]; 
     int mLength; 
     while ((mLength = mInput.read(mBuffer))>0) 
     { 
      mOutput.write(mBuffer, 0, mLength); 
     } 
     mOutput.flush(); 
     mOutput.close(); 
     mInput.close(); 
    } 
    catch (IOException mIOException) 
    { Log.i(TAG,"copyDataBase "+ mIOException+""); 

    } 
    } 

    //Open the database, so we can query it 
    public boolean openDataBase() throws SQLException 
    { 
     String mPath = DB_PATH + DB_NAME; 
     //Log.v("mPath", mPath); 
     mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
     //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
     return mDataBase != null; 
    } 

    @Override 
    public synchronized void close() 
    { 
     if(mDataBase != null) 
      mDataBase.close(); 
     super.close(); 
    } 

    @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 

    } 

} 

Этот код работает отлично для меня, я надеюсь, что это поможет вам

1

Изменить это из

while ((length = myInput.read(buffer)) >= 0) { 
      outStream.write(buffer, 0, length);    
     } 

в

while ((length = myInput.read(buffer)) >0) { 
      outStream.write(buffer, 0, length);    
     } 

Его лучше скопировать вашу базу данных по методу oncreate(), потому что в вашем классе вы это сделали. И вы должны просто вызвать свой объект класса базы данных в своей деятельности и извлечь данные из него. Поэтому сначала сделать класс с именем БДСВЯЗИ

public class DBConnect extends SQLiteOpenHelper { 
public int GetCursor; 
// ****************** Declare all the global variable 
// ****************************// 
private Context myContext; 
public String DB_PATH = "data/data/com.xyz/databases/"; // path 
// of 
// your 
// datbase 
public static String DB_NAME = "xyz.sqlite";// your database name 
static String ASSETS_DB_FOLDER = "db"; 
private SQLiteDatabase db; 

public DBConnect(Context context, String db_name) { 
    super(context, db_name, null, 2); 
    if (db != null && db.isOpen()) 
     close(); 

    this.myContext = context; 
    DB_NAME = db_name; 

    try { 
     createDataBase(); 
     openDataBase(); 
    } catch (IOException e) { 
     // System.out.println("Exception in creation of database : "+ 
     // e.getMessage()); 
     e.printStackTrace(); 
    } 

} 

public void createDataBase() throws IOException { 
    boolean dbExist = checkDataBase(); 

    if (dbExist) { 
     // System.out.println("Database Exist"); 
    } else { 
     this.getReadableDatabase(); 

     try { 
      copyDatabase(); 
     } catch (IOException e) { 
      throw new Error("Error copying database"); 
     } 
    } 
} 

private void copyDatabase() throws IOException { 
    InputStream input = myContext.getAssets().open(DB_NAME); 
    String outputFileName = DB_PATH + DB_NAME; 
    OutputStream output = new FileOutputStream(outputFileName); 

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

    // Close the streams 
    output.flush(); 
    output.close(); 
    input.close(); 
    // System.out.println(DB_NAME + "Database Copied !"); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 

} 

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

} 

public void openDataBase() throws SQLException { 
    // Open the database 
    String myPath = DB_PATH + DB_NAME; 
    db = SQLiteDatabase.openDatabase(myPath, null, 
      SQLiteDatabase.OPEN_READWRITE); 
} 

public boolean isOpen() { 
    if (db != null) 
     return db.isOpen(); 
    return false; 
} 

@Override 
public synchronized void close() { 
    if (db != null) 
     db.close(); 
    super.close(); 
} 

private boolean checkDataBase() { 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     // System.out.println("My Pathe is:- " + myPath); 
     // System.out.println("Open"); 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, 
       SQLiteDatabase.OPEN_READWRITE); 
     // System.out.println("checkDB value:" + checkDB); 
     // System.out.println("My Pathe is:- " + myPath); 
    } catch (Exception e) { 
     // database does't exist yet. 
    } 

    if (checkDB != null) { 
     // System.out.println("Closed"); 
     checkDB.close(); 
     // System.out.println("My db is:- " + checkDB.isOpen()); 
    } 

    return checkDB != null ? true : false; 
} 

public Cursor execCursorQuery(String sql) { 
    Cursor cursor = null; 
    try { 
     cursor = db.rawQuery(sql, null); 
     GetCursor = cursor.getCount(); 
     Log.i("Inside execCursorQuery try", sql); 
    } catch (Exception e) { 
     Log.i("Inside execCursorQuery exception", e.getMessage()); 
    } 
    return cursor; 
} 

public void execNonQuery(String sql) { 
    try { 
     db.execSQL(sql); 
     // Log.d("SQL", sql); 
    } catch (Exception e) { 
     // Log.e("Err", e.getMessage()); 
    } finally { 
     // closeDb(); 
    } 
} 

И в вашей деятельности, вы должны назвать его:

public class MainActivity extends Activity { 
    DBConnect db; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.layout); 
    db= new DBConnect(MainActivity.this,"databasename"); 
    } 

} 
+0

Эй, спасибо за ваш ответ. Но код все еще не работает. – Rajat

+0

так что цикл не выполнялся прямо сейчас? – Piyush

+0

Почему вы копируете свою базу данных по методу oncreate()? Вы просто хотите скопировать его или получить данные из базы данных? – Piyush

Смежные вопросы