2009-12-23 135 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

相關問題