我的应用程序的数据库需要填充大量数据,
所以在onCreate()
期间,它不仅仅是一些create table sql
说明,有很多插入。我选择的解决方案是
将所有这些指令存储在res / raw中的sql文件中
已加载Resources.openRawResource(id)
。
它运作良好,但我面对编码问题,我有一些突出 sql文件中的caharacters在我的应用程序中看起来很糟糕。这个 我的代码是这样做的:
public String getFileContent(Resources resources, int rawId) throws
IOException
{
InputStream is = resources.openRawResource(rawId);
int size = is.available();
// Read the entire asset into a local byte buffer.
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
// Convert the buffer into a string.
return new String(buffer);
}
public void onCreate(SQLiteDatabase db) {
try {
// get file content
String sqlCode = getFileContent(mCtx.getResources(), R.raw.db_create);
// execute code
for (String sqlStatements : sqlCode.split(";"))
{
db.execSQL(sqlStatements);
}
Log.v("Creating database done.");
} catch (IOException e) {
// Should never happen!
Log.e("Error reading sql file " + e.getMessage(), e);
throw new RuntimeException(e);
} catch (SQLException e) {
Log.e("Error executing sql code " + e.getMessage(), e);
throw new RuntimeException(e);
}
我发现避免这种情况的解决方案是加载sql指令
从一个巨大的static final String
而不是一个文件,所有
突出的角色显得很好。
但是加载sql指令比没有更优雅的方法
所有sql指令的static final String
属性?
答案 0 :(得分:8)
我认为你的问题就在这一行:
return new String(buffer);
您正在将字节数组转换为java.lang.String
,但您没有告诉Java / Android使用的编码。因此,由于使用了错误的编码,因此重音字符的字节数无法正确转换。
如果您使用String(byte[],<encoding>)
构造函数,则可以指定文件的编码,并且您的字符将被正确转换。
答案 1 :(得分:4)
SQL文件解决方案看起来很完美,只需要确保文件以utf8编码保存,否则所有突出的字符都将丢失。如果您不想更改文件的编码,则需要将额外的参数传递给定义文件编码的新String(bytes, charset)
。
更喜欢使用文件资源而不是静态最终字符串,以避免将所有不必要的字节加载到内存中。在手机中,您希望尽可能保存所有内存!
答案 2 :(得分:1)
我使用的是另一种方法: 而不是执行sql语句的加载(这需要很长时间才能完成),我在桌面上构建我的sqlite数据库,将它放在assets文件夹中,在android中创建一个空的sqlite数据库,并将db从assets文件夹复制到数据库夹。这是速度的巨大增长。注意,你需要先在android中创建一个空数据库,然后你可以复制并覆盖它。否则,Android将不允许您将db写入datbase文件夹。互联网上有几个例子。 顺便说一下,如果db没有文件扩展名,这种方法看起来效果最好。
答案 3 :(得分:-1)
看起来您将所有sql语句都传递到一个字符串中。这是一个问题,因为execSQL期望“单个语句不是查询”(参见文档[here] [1])。以下是一个有点丑陋但有效的解决方案。
我的所有sql语句都在这样的文件中:
INSERT INTO table1 VALUES(1,2,3);
INSERT INTO table1 VALUES(4,5,6);
INSERT INTO table1 VALUES(7,8,9);
注意文本之间的新行(分号后跟2个新行) 然后,我这样做:
String text = new String(buffer, "UTF-8");
for (String command : text.split(";\n\n")) {
try { command = command.trim();
//Log.d(TAG, "command: " + command);
if (command.length() > 0)
db.execSQL(command.trim());
}
catch(Exception e) {do whatever you need here}
我的数据列包含带有新行和分号的文本blob,因此我必须找到不同的命令分隔符。确保使用split str获得创意:使用您知道的数据中不存在的内容。
HTH 赫拉尔
[1]:http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String,java.lang.Object [])