2009-12-23 98 views
6

我的应用程序数据库需要填充大量数据,所以在onCreate()期间,这不仅仅是一些创建表sql 的说明,还有很多插入。我选择的解决方案是 将所有这些指令存储在位于res/raw的sql文件中,并且其中 加载了Resources.openRawResource(id)创建android应用程序数据库数据量大

它运行良好,但我面对的编码问题,我有一些强调 字符在SQL文件中出现在我的应用程序不好。这 我的代码来做到这一点:

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); 
     } 

我发现避免这个问题的解决方案是从一个巨大的static final String而不是文件加载SQL指令 ,所有 强调字符显示良好。

但是,是不是有一个更优雅的方式来加载SQL指令比所有SQL指令的大 static final String属性?

回答

8

我觉得你的问题是在这条线:

return new String(buffer); 

你转换字节数组中的java.lang.String但你不会告诉的Java/Android的使用的编码。因此,由于使用了错误的编码,因此重音字符的字节未被正确转换。

如果使用String(byte[],<encoding>)构造函数,你可以指定你的文件有和你的角色将被正确转换编码。

+0

非常感谢Dave – tbruyelle 2009-12-23 16:56:04

4

的SQL文件的解决方案似乎是完美的,它只是你需要确保该文件保存在UTF8编码,否则所有的加剧字符都将丢失。如果您不想更改文件的编码,那么您需要将额外参数传递给定义文件编码的新String(bytes, charset)

请喜欢使用文件资源,而不是静态的最后字符串,以避免加载到内存中的所有那些无谓的字节。在手机中,您想要保存所有可能的内存!

-1

它看起来像你所有的SQL语句在一个字符串中传递。这是一个问题,因为execSQL期待“一个不是查询的单个语句”(请参阅​​文档[here] [1])。以下是一个有点难以运行的解决方案。

我有这样的文件,我所有的SQL语句:

INSERT INTO表1 VALUES(1,2,3);

INSERT INTO表1 VALUES(4,5,6);

INSERT INTO表1 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} 

我的数据列包含新的行和分号文字的斑点,所以我必须找到不同的命令分隔符。只要确保使用split str创意即可:使用您知道的数据中不存在的内容。

HTH 赫拉尔

[1]:http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String,java.lang.Object中[])

+0

我也做了拆分(“;”),我的问题不是关于sql语句,而是编码字符。 – tbruyelle 2010-05-05 12:46:35

1

我使用了不同的方法: 相反的SQL语句的执行负载(这将需要很长一段时间的完成)之后,我在桌面上构建我的sqlite数据库,将它放在assets文件夹中,在android中创建一个空的sqlite数据库,并将资产文件夹中的数据库复制到数据库文件夹中。这是一个巨大的速度提高。请注意,您需要先在android中创建一个空数据库,然后才能复制并覆盖它。否则,Android不会允许您将数据库写入数据库文件夹。互联网上有几个例子。 顺便说一句,似乎这种方法效果最好,如果数据库没有文件扩展名。

+0

你能分享你使用的代码吗? – 2014-05-20 15:51:31

相关问题