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

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

                                    <                    uses-permission                     android:name                    ="android.permission.WRITE_EXTERNAL_STORAGE"                    ></                    uses-permission                    >                    
< uses-permission android:name ="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" ></ uses-permission >

                                     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

更多相关文章

  1. android中webView JS调用Android的方法、webView的下拉刷新(Swipe
  2. Android 数据库 大量插入 事务开启
  3. Android 7.0 使用FileProvider 在应用间共享文件
  4. android 实用sax 读取xml文件内容
  5. Android 打开相机、相册获取图片文件,支持Android 9.0系统
  6. 解决 android 在sd卡新建文件后需要重启才能找到
  7. Android遍历文件Listfile返回值为null问题解决方法适用Android8.
  8. Android上传文件至PHP服务器
  9. Android使用SQLite数据库的示例

随机推荐

  1. 原来斐波拉契数列还有这种写法,你知道吗?
  2. C++_STL常用容器总结:对组pair中关联容器
  3. c/c++字符串函数是什么类型和它是如何转
  4. 详细介绍C# 中 ASP.NET Web API 的 ROC
  5. CSS选择器有哪些?CSS选择器优先级判定
  6. 必学!C++实现多态机制满足的基本条件条件
  7. 最新总结C语言中关于指针等相关理解和使
  8. 疑惑解答: CSS中背景图片的background-pos
  9. 一招搞定C++调用Lua代码配置文件函数(附代
  10. 常见的C++中const常量用法分析讲解