android中使用sqlite、复制assets下的数据库到SD卡、支持大于1M的文件

初学android,达人忽略,欢迎扔石头.

android中使用sqlite、复制assets下的数据库到SD卡、支持大于1M的文件

如果使用SD卡,需要在AndroidManifest.xml中设置权限

  
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> < uses-permission android:name ="android.permission.WRITE_EXTERNAL_STORAGE" ></ uses-permission > < uses-permission android:name ="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" ></ uses-permission >

  
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 1 package cn.arthur.common; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 9 import android.content.Context; 10 import android.database.sqlite.SQLiteDatabase; 11 import android.database.sqlite.SQLiteDatabase.CursorFactory; 12 import android.database.sqlite.SQLiteException; 13 import android.database.sqlite.SQLiteOpenHelper; 14 15 /** 16 * @author Joshua 17 * 用法: 18 * DBHelper dbHelper = new DBHelper(this); 19 * dbHelper.createDataBase(); 20 * SQLiteDatabase db = dbHelper.getWritableDatabase(); 21 * Cursor cursor = db.query() 22 * db.execSQL(sqlString); 23 * 注意:execSQL不支持带;的多条SQL语句,只能一条一条的执行,晕了很久才明白 24 * 见execSQL的源码注释 (Multiple statements separated by ;s are not supported.) 25 * 将把assets下的数据库文件直接复制到DB_PATH,但数据库文件大小限制在1M以下 26 * 如果有超过1M的大文件,则需要先分割为N个小文件,然后使用copyBigDatabase()替换copyDatabase() 27 */ 28 public class DBHelper extends SQLiteOpenHelper { 29 // 用户数据库文件的版本 30 private static final int DB_VERSION = 1 ; 31 // 数据库文件目标存放路径为系统默认位置,cn.arthur.examples 是你的包名 32 private static String DB_PATH = " /data/data/cn.arthur.examples/databases/ " ; 33 /* 34 //如果你想把数据库文件存放在SD卡的话 35 private static String DB_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath() 36 + "/arthurcn/drivertest/packfiles/"; 37 */ 38 private static String DB_NAME = " hello.db " ; 39 private static String ASSETS_NAME = " hello.db " ; 40 41 private SQLiteDatabase myDataBase = null ; 42 private final Context myContext; 43 44 /** 45 * 如果数据库文件较大,使用FileSplit分割为小于1M的小文件 46 * 此例中分割为 hello.db.101 hello.db.102 hello.db.103 47 */ 48 // 第一个文件名后缀 49 private static final int ASSETS_SUFFIX_BEGIN = 101 ; 50 // 最后一个文件名后缀 51 private static final int ASSETS_SUFFIX_END = 103 ; 52 53 /** 54 * 在SQLiteOpenHelper的子类当中,必须有该构造函数 55 * @param context 上下文对象 56 * @param name 数据库名称 57 * @param factory 一般都是null 58 * @param version 当前数据库的版本,值必须是整数并且是递增的状态 59 */ 60 public DBHelper(Context context, String name, CursorFactory factory, int version) { 61 // 必须通过super调用父类当中的构造函数 62 super (context, name, null , version); 63 this .myContext = context; 64 } 65 66 public DBHelper(Context context, String name, int version){ 67 this (context,name, null ,version); 68 } 69 70 public DBHelper(Context context, String name){ 71 this (context,name,DB_VERSION); 72 } 73 74 public DBHelper (Context context) { 75 this (context, DB_PATH + DB_NAME); 76 } 77 78 public void createDataBase() throws IOException{ 79 boolean dbExist = checkDataBase(); 80 if (dbExist){ 81 // 数据库已存在,do nothing. 82 } else { 83 // 创建数据库 84 try { 85 File dir = new File(DB_PATH); 86 if ( ! dir.exists()){ 87 dir.mkdirs(); 88 } 89 File dbf = new File(DB_PATH + DB_NAME); 90 if (dbf.exists()){ 91 dbf.delete(); 92 } 93 SQLiteDatabase.openOrCreateDatabase(dbf, null ); 94 // 复制asseets中的db文件到DB_PATH下 95 copyDataBase(); 96 } catch (IOException e) { 97 throw new Error( " 数据库创建失败 " ); 98 } 99 } 100 } 101 102 // 检查数据库是否有效 103 private boolean checkDataBase(){ 104 SQLiteDatabase checkDB = null ; 105 String myPath = DB_PATH + DB_NAME; 106 try { 107 checkDB = SQLiteDatabase.openDatabase(myPath, null , SQLiteDatabase.OPEN_READONLY); 108 } catch (SQLiteException e){ 109 // database does't exist yet. 110 } 111 if (checkDB != null ){ 112 checkDB.close(); 113 } 114 return checkDB != null ? true : false ; 115 } 116 117 /** 118 * Copies your database from your local assets-folder to the just created empty database in the 119 * system folder, from where it can be accessed and handled. 120 * This is done by transfering bytestream. 121 * */ 122 private void copyDataBase() throws IOException{ 123 // Open your local db as the input stream 124 InputStream myInput = myContext.getAssets().open(ASSETS_NAME); 125 // Path to the just created empty db 126 String outFileName = DB_PATH + DB_NAME; 127 // Open the empty db as the output stream 128 OutputStream myOutput = new FileOutputStream(outFileName); 129 // transfer bytes from the inputfile to the outputfile 130 byte [] buffer = new byte [ 1024 ]; 131 int length; 132 while ((length = myInput.read(buffer)) > 0 ){ 133 myOutput.write(buffer, 0 , length); 134 } 135 // Close the streams 136 myOutput.flush(); 137 myOutput.close(); 138 myInput.close(); 139 } 140 141 // 复制assets下的大数据库文件时用这个 142 private void copyBigDataBase() throws IOException{ 143 InputStream myInput; 144 String outFileName = DB_PATH + DB_NAME; 145 OutputStream myOutput = new FileOutputStream(outFileName); 146 for ( int i = ASSETS_SUFFIX_BEGIN; i < ASSETS_SUFFIX_END + 1 ; i ++ ) { 147 myInput = myContext.getAssets().open(ASSETS_NAME + " . " + i); 148 byte [] buffer = new byte [ 1024 ]; 149 int length; 150 while ((length = myInput.read(buffer)) > 0 ){ 151 myOutput.write(buffer, 0 , length); 152 } 153 myOutput.flush(); 154 myInput.close(); 155 } 156 myOutput.close(); 157 } 158 159 @Override 160 public synchronized void close() { 161 if (myDataBase != null ){ 162 myDataBase.close(); 163 } 164 super .close(); 165 } 166 167 /** 168 * 该函数是在第一次创建的时候执行, 169 * 实际上是第一次得到SQLiteDatabase对象的时候才会调用这个方法 170 */ 171 @Override 172 public void onCreate(SQLiteDatabase db) { 173 } 174 175 /** 176 * 数据库表结构有变化时采用 177 */ 178 @Override 179 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 180 } 181 182 } 183

你可能感兴趣的:(android)