设为首页 收藏本站
查看: 1371|回复: 0

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

[复制链接]

尚未签到

发表于 2016-12-1 11:54:59 | 显示全部楼层 |阅读模式
  初学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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-308223-1-1.html 上篇帖子: SQLite 和 listview baseAdapter结合的例子 下篇帖子: 无废话Android 系列教程35 [Android下的数据库SQLite事务概念及使用&&测试]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表