2011-11-08 44 views
3

我嘗試從資產目錄複製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 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 

    } 

} 

嘗試一切!我試着玩延期!但我仍然得到一個錯誤: 錯誤複製DB:java.io.FileNotFoundException: /data/data/com.mypackage/databases/database.sqlite (No such file or directory)

我檢查了模擬器,我的文件在那裏,所以我應該能夠寫入它! 請幫忙!這讓我瘋狂!

UPD我試圖把它放在SD卡上,它的工作。但仍然無法得到爲什麼我不能將它寫入應用程序數據文件夾。

回答

6

我用這個助手和工作正常:

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的,我的數據庫是爲資產/數據庫/

+0

謝謝!它的工作,我現在試着找出什麼是錯的 –

+0

我怎麼能在複製的數據庫中添加記錄? –

3

我有同樣的問題,我用另一種方法解決了它。 在開始的時候,我聲明瞭數據庫路徑爲大家做的:

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

這是一個確切路徑,沒有錯。但是當我嘗試打開OutPutFileStream來複制數據庫時總是失敗。我不知道爲什麼。然後,我改變成開放式如下數據庫的方式:

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

這個問題有解決奔。好驚訝。

希望這會有所幫助。

1
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); 
      } 
     } 
    } 
} 
+0

你應該添加一些評論。 –

1

請檢查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(); 
} 
相關問題