android - 平板电脑的 SQLITE 数据库复制失败
问题描述
我正面临一个奇怪的情况。
我正在使用以下代码从 assets 文件夹创建一个 sqlite db。对于任何手机,它都可以正常工作。但对于平板电脑,复制失败了。例如:示例 db 为 526kb,但为平板电脑创建的只有 12kb。我可以在模拟器中手动上传文件。但我真的需要代码适用于平板电脑,而不需要对真正的平板电脑进行任何手动干预。
public class DatabaseHelper extends SQLiteOpenHelper {
private static String DB_PATH = "C:/temp/";
private static String DB_NAME = "sample.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
if (android.os.Build.VERSION.SDK_INT >= 4.2) {
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
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;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
//System.exit(0);
// Path to the just created empty db
String outFileName = DB_PATH+DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
String myPath = DB_PATH+DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
}
解决方案
我遇到了同样的问题,直到我发现一个晦涩的线程说某些类型的对象在添加到资产文件夹时会被压缩。如果您将数据库命名为 .db 或 .sql,它将被压缩。您需要将其命名为 .jpg 并且它不会被压缩。然后,当您在运行时将数据库从资产复制到应用程序的数据文件夹时,您可以随意命名:
private String DB_PATH = "";
private static String DB_IN = "mydatabase.jpg";
private static String DB_NAME = "mydatabase.db";
private void copyDataBase() throws IOException{
DB_PATH = myContext.getFilesDir().getParentFile().getPath() + "/databases/";
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_IN);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
推荐阅读
- c++ - CUDA 10.0 和 10.2 之间的 Pytorch 推理时间差异
- awk - 我如何使用 awk 进行分组
- css - 使用 flexbox 固定位置
- python - Django:子进程连续输出到 HTML 视图
- java - 替换forEach语句下的if条件
- c# - EF Core 对多个连接表进行分组
- javascript - 记录更新的 lwc 数据表
- swift - UIButton addTarget 没有被调用
- python-3.x - 在 Ubuntu 18.04 上通过 conda 安装 textblob 时出错
- python - aws appsync graphql api与python