バックアップのために、単純なSQLite
エクスポート/インポートを実装しようとしています。エクスポートは、生のcurrent.db
ファイル。インポートのためにしたいのは、古いcurrent.db
ファイルを作成し、imported.db
ファイルからcurrent.db
。これは可能ですか?このソリューションを試すと、次のエラーが表示されます。
06-30 13:33:38.831: ERROR/SQLiteOpenHelper(23570):
Android.database.sqlite.SQLiteDatabaseCorruptException: error code 11: database disk image is malformed
SQLite
ブラウザで生のデータベースファイルを見ると、うまく見えます。
アプリケーションの1つでSQLiteOpenHelper
でこのコードを使用して、データベースファイルをインポートします。
編集:質問にFileUtils.copyFile()
メソッドを貼り付けました。
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();
}
}
}
}
}
必要に応じて、古いデータベースファイルを削除することを忘れないでください。
これは、必要な名前を付けることができるバックアップフォルダーという名前のフォルダーにデータベースをエクスポートする簡単な方法であり、同じフォルダーからデータベースをインポートする簡単な方法です。
public class ExportImportDB extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//creating a new folder for the database to be backuped to
File direct = new File(Environment.getExternalStorageDirectory() + "/Exam Creator");
if(!direct.exists())
{
if(direct.mkdir())
{
//directory is created;
}
}
exportDB();
importDB();
}
//importing database
private void importDB() {
// TODO Auto-generated method stub
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath= "//data//" + "PackageName"
+ "//databases//" + "DatabaseName";
String backupDBPath = "/BackupFolder/DatabaseName";
File backupDB= new File(data, currentDBPath);
File currentDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), backupDB.toString(),
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
.show();
}
}
//exporting database
private void exportDB() {
// TODO Auto-generated method stub
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath= "//data//" + "PackageName"
+ "//databases//" + "DatabaseName";
String backupDBPath = "/BackupFolder/DatabaseName";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), backupDB.toString(),
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
.show();
}
}
}
続行するには、この許可を追加することを忘れないでください
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>
楽しい
SQLITEまたはROOMではなく、dbをエクスポートするには:
まず、AndroidManifest.xmlファイルに次の許可を追加します。
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
次に、db関数をコーディングします。
private void exportDB() {
try {
File dbFile = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());
FileInputStream fis = new FileInputStream(dbFile);
String outFileName = DirectoryName + File.separator +
DATABASE_NAME + ".db";
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
} catch (IOException e) {
Log.e("dbBackup:", e.getMessage());
}
}
フォルダー名が現在の日付であるフォルダーを毎日作成:
public void createBackup() {
sharedPref = getSharedPreferences("dbBackUp", MODE_PRIVATE);
editor = sharedPref.edit();
String dt = sharedPref.getString("dt", new SimpleDateFormat("dd-MM-yy").format(new Date()));
if (dt != new SimpleDateFormat("dd-MM-yy").format(new Date())) {
editor.putString("dt", new SimpleDateFormat("dd-MM-yy").format(new Date()));
editor.commit();
}
File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "BackupDBs");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
DirectoryName = folder.getPath() + File.separator + sharedPref.getString("dt", "");
folder = new File(DirectoryName);
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
exportDB();
}
} else {
Toast.makeText(this, "Not create folder", Toast.LENGTH_SHORT).show();
}
}
.db拡張子なしでDATABASE_NAMEを割り当て、そのデータ型は文字列です