2011-11-08 4 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(); 
} 
관련 문제