База данных моего приложения должна быть заполнена большим количеством данных, таким образом, во время onCreate()
, это не, только некоторые составляют таблицу sql инструкции, существует много вставок. Решение, которое я выбрал, состоит в том, чтобы сохранить все это инструкции в sql файле, расположенном в res/raw и который загружается Resources.openRawResource(id)
.
Это работает хорошо, но я сталкиваюсь к кодированию проблемы, я имею, некоторые подчеркнули caharacters в 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 инструкциями?
Я думаю, ваша проблема в этой строке:
return new String(buffer);
Вы конвертируете массив байтов в java.lang.String
, но вы не говорите Java / Android - используемая кодировка. Таким образом, байты для ваших акцентированных символов не преобразуются правильно, поскольку используется неправильная кодировка.
Если вы используете конструктор String (byte [],
, вы можете указать кодировку в вашем файле есть, и ваши символы будут преобразованы правильно.
Решение с файлом SQL кажется идеальным, просто вам нужно убедиться, что файл сохранен в кодировке utf8, иначе все акцентированные символы будут потеряны. Если вы не хотите изменять кодировку файла, вам необходимо передать дополнительный аргумент новой String (bytes, charset)
, определяющей кодировку файла.
Предпочитайте использовать ресурсы файла вместо статических final String, чтобы все ненужные байты не загружались в память. В мобильных телефонах вы хотите сохранить всю возможную память!
Похоже, вы передаете все операторы 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 [])