2014-01-21 55 views
-3

我正在創建使用現有sqlite數據庫的Dictionary應用程序。我已將數據庫放置在資產文件夾中,並且在第一次啓動應用程序時使用以下代碼來複制數據庫。 (我從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不會複製數據庫。我使用了Log工具,並且發現while循環從不運行。 這段代碼有什麼問題。 謝謝。

+0

只需將while循環的行更改爲'while((length = myInput.read(buffer))> 0){'只需將它與'>'比較而不是'> ='。 – GrIsHu

+0

Ya繼續使用GrlsHu並且您還需要在轉到FileOutputStream之前創建文件 –

+2

在SO和其他地方有十幾個這樣的例子。應該用Google搜索。 – 323go

回答

2

更改while循環,如下:

除了你的條件>=更大大於或等於將其更改爲只有>大於

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()方法上的數據庫,因爲在你的課堂上你做到了。你必須在你的activity中調用你的數據庫類對象並從中獲取數據。因此,首先讓班命名爲DBCONNECT

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

所以while循環現在不執行嗎? – Piyush

+0

你爲什麼要在oncreate()方法上覆制你的數據庫?你只是想複製它或從數據庫中獲取數據? – Piyush

相關問題