【问题标题】:Creating android app Database with big amount of data创建具有大量数据的android应用程序数据库
【发布时间】:2009-12-23 16:28:43
【问题描述】:

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

它运作良好,但我面临编码问题,我有一些强调 在我的应用程序中出现错误的 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);
        }

我发现避免这种情况的解决方案是加载 sql 指令 从一个巨大的static final String 而不是一个文件,以及所有 重音字符看起来很好。

但是没有比大的加载 sql 指令更优雅的方式吗? static final String 属性与所有 sql 指令?

【问题讨论】:

    标签: java database android


    【解决方案1】:

    我认为你的问题出在这一行:

    return new String(buffer);
    

    您正在将字节数组转换为java.lang.String,但您并没有告诉Java/Android 要使用的编码。因此,由于使用了错误的编码,重音字符的字节没有被正确转换。

    如果您使用String(byte[],<encoding>) 构造函数,您可以指定文件的编码,并且您的字符将被正确转换。

    【讨论】:

      【解决方案2】:

      SQL 文件解决方案看起来很完美,只是您需要确保文件以 utf8 编码保存,否则所有重读字符都会丢失。如果您不想更改文件的编码,则需要将额外的参数传递给定义文件编码的新String(bytes, charset)

      更喜欢使用文件资源而不是静态最终字符串,以避免将所有那些不必要的字节加载到内存中。在手机中,您希望尽可能节省所有内存!

      【讨论】:

        【解决方案3】:

        我正在使用不同的方法: 我没有执行大量的 sql 语句(这将需要很长时间才能完成),而是在桌面上构建我的 sqlite 数据库,将其放在 assets 文件夹中,在 android 中创建一个空的 sqlite db 并将 db 从 assets 文件夹复制到数据库文件夹。这是速度的巨大提升。注意,你需要先在android中创建一个空数据库,然后你可以复制和覆盖它。否则,Android 将不允许您将 db 写入数据库文件夹。网上有几个例子。 顺便说一句,如果 db 没有文件扩展名,这种方法似乎效果最好。

        【讨论】:

          【解决方案4】:

          看起来您正在将所有 sql 语句都传递到一个字符串中。这是一个问题,因为 execSQL 需要“不是查询的单个语句”(参见文档 [此处] [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}
          

          我的数据列包含带有换行符和分号的文本块,因此我必须找到不同的命令分隔符。请务必使用拆分 str 获得创意:使用您知道数据中不存在的东西。

          HTH 赫拉尔多

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

          【讨论】:

          • 我也做了一个 split(";") ,我的问题不在于 sql 语句,而在于编码字符。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-28
          • 2018-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-01
          相关资源
          最近更新 更多