Java Android上SQLite数据库的简单导出和导入
我正在尝试实现一个简单的Java Android上SQLite数据库的简单导出和导入,java,android,database,sqlite,Java,Android,Database,Sqlite,我正在尝试实现一个简单的SQLiteexport/import来进行备份。导出只是存储原始current.db文件的副本。对于导入,我要做的是删除旧的current.db文件,并将imported.db文件重命名为current.db。这可能吗?尝试此解决方案时,出现以下错误: 06-30 13:33:38.831: ERROR/SQLiteOpenHelper(23570): android.database.sqlite.SQLiteDatabaseCorruptException:
SQLite
export/import来进行备份。导出只是存储原始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
浏览器中查看原始数据库文件,它看起来很好。我在一个应用程序的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();
}
}
}
}
}
如有必要,请不要忘记删除旧数据库文件。这是一种将数据库导出到名为backup folder的文件夹的简单方法,您可以根据需要将其命名,这是一种从同一文件夹导入数据库的简单方法
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>
享受导出db而不是SQLITE或ROOM的乐趣: 首先,在AndroidManifest.xml文件中添加此权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
每天创建文件夹,文件夹名称为当前日期:
分配不带.db扩展名的数据库名称,其数据类型为string
如果你想把这个放在科特林。而且工作得很好
private fun exportDbFile() {
try {
//Existing DB Path
val DB_PATH = "/data/packagename/databases/mydb.db"
val DATA_DIRECTORY = Environment.getDataDirectory()
val INITIAL_DB_PATH = File(DATA_DIRECTORY, DB_PATH)
//COPY DB PATH
val EXTERNAL_DIRECTORY: File = Environment.getExternalStorageDirectory()
val COPY_DB = "/mynewfolder/mydb.db"
val COPY_DB_PATH = File(EXTERNAL_DIRECTORY, COPY_DB)
File(COPY_DB_PATH.parent!!).mkdirs()
val srcChannel = FileInputStream(INITIAL_DB_PATH).channel
val dstChannel = FileOutputStream(COPY_DB_PATH).channel
dstChannel.transferFrom(srcChannel,0,srcChannel.size())
srcChannel.close()
dstChannel.close()
} catch (excep: Exception) {
Toast.makeText(this,"ERROR IN COPY $excep",Toast.LENGTH_LONG).show()
Log.e("FILECOPYERROR>>>>",excep.toString())
excep.printStackTrace()
}
}
在Android上导入和导出SQLite数据库 下面是我将数据库导出到设备存储的函数
private void exportDB(){
String DatabaseName = "Sycrypter.db";
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
FileChannel source=null;
FileChannel destination=null;
String currentDBPath = "/data/"+ "com.synnlabz.sycryptr" +"/databases/"+DatabaseName ;
String backupDBPath = SAMPLE_DB_NAME;
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
try {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
Toast.makeText(this, "Your Database is Exported !!", Toast.LENGTH_LONG).show();
} catch(IOException e) {
e.printStackTrace();
}
}
下面是我将数据库从设备存储导入android应用程序的功能
private void importDB(){
String dir=Environment.getExternalStorageDirectory().getAbsolutePath();
File sd = new File(dir);
File data = Environment.getDataDirectory();
FileChannel source = null;
FileChannel destination = null;
String backupDBPath = "/data/com.synnlabz.sycryptr/databases/Sycrypter.db";
String currentDBPath = "Sycrypter.db";
File currentDB = new File(sd, currentDBPath);
File backupDB = new File(data, backupDBPath);
try {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
Toast.makeText(this, "Your Database is Imported !!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
记得给你喜欢的答案投票,帮助社区知道哪些是好的,哪些是垃圾。上面奥斯汀的答案对我也很有用。需要注意的一点是,这里没有提到的是字符串path=Environment.getExternalStorageDirectory().toString()+“/{appName}/”;设置SD卡上的写入路径。这很有意义。这是一些好建议。实际上,我是在自己的应用程序中完成的,但在这个演示代码中只包含了一个字符串文字作为占位符。@AustynMahoney:这对非根设备有效吗?对于指向db:
上下文的路径。getDatabasePath(“db_filename”)
不知何故,importDB和exportDB过程完全相同?错误:如果仔细看,“currentDB”变量引用importDB中的数据文件夹文件和exportDB中的sd文件夹。还有一个问题,您如何通过单击android上的按钮来实现它。如果在复制过程中数据库文件发生更改,会发生什么情况?请小心该实现。在数据库导出期间,它在任何错误情况下都会发生内存泄漏。原因是finally中的两个流(FileInputStream和FileOutputStream)都未关闭。这给了我一个无法找到此类文件或目录的错误
private void exportDB(){
String DatabaseName = "Sycrypter.db";
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
FileChannel source=null;
FileChannel destination=null;
String currentDBPath = "/data/"+ "com.synnlabz.sycryptr" +"/databases/"+DatabaseName ;
String backupDBPath = SAMPLE_DB_NAME;
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
try {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
Toast.makeText(this, "Your Database is Exported !!", Toast.LENGTH_LONG).show();
} catch(IOException e) {
e.printStackTrace();
}
}
private void importDB(){
String dir=Environment.getExternalStorageDirectory().getAbsolutePath();
File sd = new File(dir);
File data = Environment.getDataDirectory();
FileChannel source = null;
FileChannel destination = null;
String backupDBPath = "/data/com.synnlabz.sycryptr/databases/Sycrypter.db";
String currentDBPath = "Sycrypter.db";
File currentDB = new File(sd, currentDBPath);
File backupDB = new File(data, backupDBPath);
try {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
Toast.makeText(this, "Your Database is Imported !!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}