我尝试从资产目录复制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卡上然后就可以了。但仍然无法理解为什么我无法将其写入app数据文件夹。
答案 0 :(得分:7)
我使用这个助手并且工作正常:
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 / databases /
答案 1 :(得分:3)
我有同样的问题,我用另一种方法修复了它。 一开始,我按照每个人的说法声明了数据库路径:
dbPath="data/data/<my package name>/databases/data.db"
这是一个确切的路径,没有错。但是当我尝试打开OutPutFileStream来复制数据库时,它总是会失败。我不知道为什么。然后,我改变了打开数据库的方式,如下所示:
dbPath = context.getDatabasePath(dbName);
OutputStream myOutput = new FileOutputStream(dbPath.getAbsolutePath());
这个问题已经解决了。太惊讶了。
希望这有帮助。
答案 2 :(得分:2)
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);
}
}
}
}
答案 3 :(得分: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();
}