将数据库文件复制到本地存储

时间:2019-03-22 04:40:15

标签: android sqlite local-storage

我在assete文件夹中有一个sqlite数据库。

我要将其复制到本地存储。

我使用此代码,它复制没有表的数据库。当我想在sqlliteeditor中打开数据库时,出现错误14。

  private void copyDataBase2() throws IOException {
    OutputStream os = new FileOutputStream(  "/data/data/pakagename/Learning.db");
    InputStream is = context.getAssets().open("databases/Learning.db");
    byte[] buffer = new byte[1024];
    int length;
    while ((length = is.read(buffer)) > 0) {
        os.write(buffer, 0, length);
    }
    is.close();
    os.flush();
    os.close();
}

3 个答案:

答案 0 :(得分:0)

尝试像这样复制数据库文件:

public class DbHelper extends SQLiteOpenHelper {
    private static String DB_PATH = new File(getFilesDir(), "databases").getPath();
    private static String DB_NAME = "test_db.db";
    private SQLiteDatabase dataBase;
    private final Context fContext;
    public DbHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.fContext = context;
    }
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
            //ничего не делаем – файл базы данных уже есть
        } else {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            //файл базы данных отсутствует
        }
        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }
    private void copyDataBase() throws IOException {
        InputStream input = fContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream output = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        output.flush();
        output.close();
        input.close();
    }
    public void openDataBase() throws SQLException {
        String path = DB_PATH + DB_NAME;
        dataBase = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
    }
    @Override
    public synchronized void close() {
        if (dataBase != null)
            dataBase.close();
        super.close();
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

如果您使用API​​ 19或更高版本:

String db_path = fContext.getDatabasePath(DB_NAME);
  

当我想在sqlliteeditor中打开数据库时,出现错误14。

我也建议您检查数据库文件。如果在编辑器中将其打开时发生错误,则可能是文件复制算法中没有此问题。

答案 1 :(得分:0)

这只是文件复制,无论是数据库还是什么都无所谓。实际上,上面的代码并不了解表,因此无法在没有表的情况下复制数据库。

您可以比较两个db文件的哈希码。为此,您可以更改代码以将文件复制到外部存储,而不是暂时将应用程序的数据目录复制到 。然后通过adb将文件检索回PC并进行比较。

根据您的代码,没有问题,它们应该是相同的。

数据库文件本身可能已损坏(或)您以错误的方式打开了文件。

答案 2 :(得分:0)

尝试使用此:

private void copyDB(Context context) throws Exception{
    File destinationDirectory = new File(Environment.getExternalStorageDirectory() + "/Destination/");
    File destinationFile = new File(destinationDirectory + "/myDatabase.db");
    if (!destinationDirectory.isDirectory()) {
        destinationDirectory.mkdir();
        destinationFile.createNewFile();
    }
    File dbFile = context.getDatabasePath("my_database.db");
    if (dbFile.exists()) {
        copyFile(dbFile.getPath(), logFile.getAbsolutePath(), false);
    }
}

private boolean copyFile(String sPath, String dPath, boolean isDeleteSourceDir) {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        File sourceFile = new File(sPath);
        fis = new FileInputStream(sourceFile);
        File dir = new File(dPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File outfile = new File(dPath);
        outfile.delete();
        if (!outfile.exists()) {
            outfile.createNewFile();
        }
        fos = new FileOutputStream(outfile);
        byte[] block = new byte[1000];
        int i;
        while ((i = fis.read(block)) != -1) {
            fos.write(block, 0, i);
        }
        fos.close();
        if (isDeleteSourceDir) {
            deleteDirectory(new File(sPath));
        }
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        fis.close();
        fos.close();
    }
}