Search code examples
javaandroiddatabasesqlite

Simple export and import of a SQLite database on Android


I am trying to implement a simple SQLite export/import for backup purposes. Export is just a matter of storing a copy of the raw current.db file. What I want to do for import is to just delete the old current.db file and rename the imported.db file to current.db. Is this possible? When I try this solution, I get the following error:

06-30 13:33:38.831: ERROR/SQLiteOpenHelper(23570):
    android.database.sqlite.SQLiteDatabaseCorruptException: error code 11: database disk image is malformed

If I look at the raw database file in a SQLite browser it looks fine.


Solution

  • I use this code in the SQLiteOpenHelper in one of my applications to import a database file.

    EDIT: I pasted my FileUtils.copyFile() method into the question.

    SQLiteOpenHelper

    public static String DB_FILEPATH = "/data/data/{package_name}/databases/database.db";
    
    /**
     * Copies the database file at the specified location over the current
     * internal application database.
     * */
    public boolean importDatabase(String dbPath) throws IOException {
    
        // Close the SQLiteOpenHelper so it will commit the created empty
        // database to internal storage.
        close();
        File newDb = new File(dbPath);
        File oldDb = new File(DB_FILEPATH);
        if (newDb.exists()) {
            FileUtils.copyFile(new FileInputStream(newDb), new FileOutputStream(oldDb));
            // Access the copied database so SQLiteHelper will cache it and mark
            // it as created.
            getWritableDatabase().close();
            return true;
        }
        return false;
    }
    

    FileUtils

    public class FileUtils {
        /**
         * Creates the specified <code>toFile</code> as a byte for byte copy of the
         * <code>fromFile</code>. If <code>toFile</code> already exists, then it
         * will be replaced with a copy of <code>fromFile</code>. The name and path
         * of <code>toFile</code> will be that of <code>toFile</code>.<br/>
         * <br/>
         * <i> Note: <code>fromFile</code> and <code>toFile</code> will be closed by
         * this function.</i>
         * 
         * @param fromFile
         *            - FileInputStream for the file to copy from.
         * @param toFile
         *            - FileInputStream for the file to copy to.
         */
        public static void copyFile(FileInputStream fromFile, FileOutputStream toFile) throws IOException {
            FileChannel fromChannel = null;
            FileChannel toChannel = null;
            try {
                fromChannel = fromFile.getChannel();
                toChannel = toFile.getChannel();
                fromChannel.transferTo(0, fromChannel.size(), toChannel);
            } finally {
                try {
                    if (fromChannel != null) {
                        fromChannel.close();
                    }
                } finally {
                    if (toChannel != null) {
                        toChannel.close();
                    }
                }
            }
        }
    }
    

    Don't forget to delete the old database file if necessary.