J'essaie d'implémenter une simple exportation/importation SQLite
à des fins de sauvegarde. L'exportation consiste simplement à stocker une copie du fichier current.db
brut. Ce que je veux faire pour importer consiste à simplement supprimer l'ancien fichier current.db
et à renommer le fichier imported.db
en current.db
. Est-ce possible? Lorsque j'essaie cette solution, j'obtiens le message d'erreur suivant:
06-30 13:33:38.831: ERROR/SQLiteOpenHelper(23570):
Android.database.sqlite.SQLiteDatabaseCorruptException: error code 11: database disk image is malformed
Si je regarde le fichier de base de données brute dans un navigateur SQLite
, tout se passe bien.
J'utilise ce code dans la variable SQLiteOpenHelper
de l'une de mes applications pour importer un fichier de base de données.
EDIT: J'ai collé ma méthode FileUtils.copyFile()
dans la 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();
}
}
}
}
}
N'oubliez pas de supprimer l'ancien fichier de base de données si nécessaire.
Il s’agit d’une méthode simple pour exporter la base de données dans un dossier nommé dossier de sauvegarde. Vous pouvez également la nommer comme vous le souhaitez et une méthode simple
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();
}
}
}
N'oubliez pas d'ajouter cette permission pour continuer
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>
Prendre plaisir
Pour exporter la base de données plutôt que ce soit SQLITE ou ROOM:
Tout d'abord, ajoutez cette permission dans le fichier AndroidManifest.xml:
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
Deuxièmement, nous allons coder les fonctions de la base de données:
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());
}
}
Créer un dossier tous les jours avec le nom du dossier indiqué Date actuelle:
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();
}
}
Attribuez le DATABASE_NAME sans l'extension .db et son type de données est une chaîne