android raw读取超过1M文件的方法(文件压缩方法)

 

近日在琢磨android系统,程序中用到了sqlite数据库,一切代码妥当,在发布时遇到点问题,就是raw单个文件不能超过1M,否则会报错"Data exceeds UNCOMPRESS_DATA_MAX ",而我的数据库的初始容量就是5M啦,网上寻找多时,大致分成两种方法:
1>是将文件移动到sdcard中.这样倒是不受文件大小限制,不过对于apk的发布....不用我多说了吧.
2>将单个文件分割成多个1M以下的小文件....这个倒是个方法.只是用上去总是有点别扭.需要找文件分割工具...或者自己写一个.

     于是,自然想到用压缩的方法.android的sdk完全采用了java的zip压缩类.这就为我实现压缩提供了极大方便.经过测试,本人的sqlite库,原始大小为5M,用zip压缩后700K,哈哈,完全满足系统限制.然后在读取时,解压缩到apk的数据库默认目录下即可. 不在废话,以下是本人的代码:

 

  1 import java.io.BufferedInputStream;
2
3 import java.io.File;
4
5 import java.io.FileOutputStream;
6
7 import java.io.IOException;
8
9 import java.io.InputStream;
10
11 import java.io.OutputStream;
12
13 import java.util.zip.ZipEntry;
14
15 import java.util.zip.ZipInputStream;
16
17
18 import android.app.ProgressDialog;
19
20 import android.content.Context;
21
22 import android.database.Cursor;
23
24 import android.database.SQLException;
25
26 import android.database.sqlite.SQLiteDatabase;
27
28 import android.database.sqlite.SQLiteOpenHelper;
29
30 import android.os.AsyncTask;
31
32
33 public class DBSourse {
34
35 private static final String DATABASE_NAME = "Test.db";
36
37 private static final int DATABASE_VERSION = 1;
38
39 private DatabaseHelper mDbHelper;
40
41 private SQLiteDatabase mDb;
42
43 private final Context mCtx;
44
45 private static int mDBRawResource = 0;
46
47 public DBSourse(Context ctx,int DBRawResource) {
48
49 this.mCtx = ctx;
50
51 mDBRawResource = DBRawResource;
52
53 }
54
55 public DBSourse(Context ctx) {
56
57 this.mCtx = ctx;
58
59 if (mDBRawResource == 0)
60
61 new Exception("必须指定以zip压缩的数据库Raw文件");
62
63 }
64
65
66 public static class DatabaseHelper extends SQLiteOpenHelper {
67
68 DatabaseHelper(Context context) {
69
70 super(context, DATABASE_NAME, null, DATABASE_VERSION);
71
72 }
73
74
75 @Override
76
77 public void onCreate(SQLiteDatabase db) {
78
79
80 }
81
82
83 @Override
84
85 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
86
87 }
88
89 }
90
91
92
93
94
95 class DBDialogTask extends AsyncTask<String, Integer, Integer> {
96
97 ProgressDialog m_pDialog;
98
99 int StreamLen;
100
101 @Override
102
103 protected Integer doInBackground(String... params) { // 后台进程执行的具体计算在这里实现
104
105 String dbPathString = params[0];
106
107 int len = 1024;//
108
109 int readCount = 0, readSum = 0;
110
111 byte[] buffer = new byte[len];
112
113 InputStream inputStream;
114
115 OutputStream output;
116
117 try {
118
119 inputStream = mCtx.getResources().openRawResource(mDBRawResource); //这里就是Raw文件引用位置
120
121 output = new FileOutputStream(dbPathString);
122
123
124
125 ZipInputStream zipInputStream = new ZipInputStream(
126
127 new BufferedInputStream(inputStream));
128
129 ZipEntry zipEntry = zipInputStream.getNextEntry();
130
131 BufferedInputStream b = new BufferedInputStream(
132
133 zipInputStream);
134
135 StreamLen = (int) zipEntry.getSize();
136
137 while ((readCount = b.read(buffer)) != -1) {
138
139 // readCount = b.read(buffer);
140
141 output.write(buffer,0,readCount);
142
143 readSum = readSum + readCount;
144
145 publishProgress(readSum);
146
147 }
148
149 output.flush();
150
151 output.close();
152
153 } catch (IOException e) {
154
155 e.printStackTrace();
156
157 }
158
159 return StreamLen;
160
161 }
162
163
164 @Override
165
166 // 运行于UI线程。如果在doInBackground(Params...)
167
168 // 中使用了publishProgress(Progress...),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。
169
170 protected void onProgressUpdate(Integer... values) {
171
172 super.onProgressUpdate(values);
173
174 if (m_pDialog.getMax() != StreamLen)
175
176 m_pDialog.setMax(StreamLen);
177
178 m_pDialog.setProgress(values[0]);
179
180
181 }
182
183
184 @Override
185
186 // 执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。
187
188 protected void onPreExecute() {
189
190 super.onPreExecute();
191
192
193 m_pDialog = new ProgressDialog(mCtx);
194
195 m_pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
196
197 m_pDialog.setTitle("提示");
198
199 m_pDialog.setMessage("正在升级数据库,请勿关闭应用程序");
200
201 m_pDialog.show();
202
203
204 }
205
206
207 @Override
208
209 // 运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params...)的返回值
210
211 protected void onPostExecute(Integer result) {
212
213 super.onPostExecute(result);
214
215 m_pDialog.setProgress(result);
216
217 m_pDialog.cancel();
218
219 if (onDBInstalledListener != null)
220
221 onDBInstalledListener.OnDBInstalled();
222
223 }
224
225
226 }
227
228
229
230 protected OnDBInstalledListener onDBInstalledListener;
231
232
233
234
235 public void setOnDBInstalledListener(OnDBInstalledListener onDBInstalledListener) {
236
237 this.onDBInstalledListener = onDBInstalledListener;
238
239 }
240
241
242
243 public void InstallDatabase() {
244
245 mDbHelper = new DatabaseHelper(mCtx);
246
247 SQLiteDatabase sdbreader = mDbHelper.getReadableDatabase();
248
249 File dbfile = new File(sdbreader.getPath());
250
251 if (dbfile.length()<4096){//依据数据库大小判断,是否需要执行安装.暂时没仔细想别的办法
252
253 DBDialogTask dialogTask = new DBDialogTask();
254
255 dialogTask.execute(sdbreader.getPath());
256
257 }else{
258
259 if (onDBInstalledListener != null)
260
261 onDBInstalledListener.OnDBInstalled(); //这里可以委托一个方法,用以安装完数据库后的初始化工作
262
263 }
264
265 }
266
267
268 public DBSourse open() throws SQLException {
269
270 if( mDbHelper == null)
271
272 mDbHelper = new DatabaseHelper(mCtx);
273
274 if (mDb == null)
275
276 mDb = mDbHelper.getWritableDatabase();
277
278 if (!mDb.isOpen())
279
280 mDb = mDbHelper.getWritableDatabase();
281
282 return this;
283
284 }
285
286
287 public void close() {
288
289 mDbHelper.close();
290
291 }
292
293
294
295 public Cursor GetSomeData() {
296
297 return mDb.query("table",
298
299 new String[] { "_id", "a1", "a2" }, "a1 = 1",
300
301 null, null, null, "a2");
302
303 }
304
305
306
307 public interface OnDBInstalledListener{
308
309 void OnDBInstalled();
310
311 }
312
313 }

然后在需要调用数据库的地方,创建此类,调用InstallDatabase方法.由线程从raw中解压数据库资源...为了在数据库安装完成后执行某些操作还可以绑定方法OnDBInstalledListener

对了,忘记说了,将sqlite数据库从ddms中导出后,用zip压缩,然后存入raw文件夹即可.(别问我怎么将文件压缩成zip.还有别压缩成rar格式.).至于当压缩后的文件依然超过1M怎么办呢?我倒是没琢磨,不过初步考虑有两种方法:
1>分割压缩后的文件(这个方法纯属于杂交...).
2>分卷压缩.我倾向于这个办法,不过没有考虑如何实现.哪位大牛实现了,烦劳通告一下.呵呵

有事儿联系.完事.

 

文章来自:http://www.cnblogs.com/yaoshi641/archive/2010/12/26/1917443.html


 

posted on 2012-03-21 01:00  simpleceo  阅读(789)  评论(0编辑  收藏  举报

导航