`
thecloud
  • 浏览: 881756 次
文章分类
社区版块
存档分类
最新评论

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics