Android开发-asset中文件超过1M的解决方法

res/raw和assets的相同点:

 

1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。

 

res/raw和assets的不同点: 
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹

读取文件资源:

1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作

InputStream is = getResources().openRawResource(R.id.filename);

 2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作

AssetManager am =  null ;  
am = getAssets();  
InputStream is = am.open("filename" );

 在未知目录下有哪些文件,该去和获取这些文件的名称并把文件拷贝到目标目录中呢?

String[] files = getAssets().list("");

来获取assets目录下所有文件夹和文件的名称,再通过这些名称再读取我们想要的文件。

Android 对asset与raw的限制

在读取这两个资源文件夹中的文件时会有一定的限制,即单个文件大小不能超过1M ,如果读取超过1M的文件会报 "Data exceeds UNCOMPRESS_DATA_MAX (1314625 vs 1048576)" 的IOException。

如何解决呢:

首先想到的是分割文件,再去合并并文件。

假设我们现在要把一个超过1M的文件在程序启动时拷贝到sdcard中

1.先把需要拷贝的大文件分割成若干个大小小于1M的小文件(事先写个程序来分隔或者使用一些工具,我这里直接写了个程序),把这些 小文件放在assets文件夹中。

2.在程序启动时我们获取这些小文件的文件名,当然我们得事先规定小文件的命名方式方便我们来获取这些文件名。
3.通过获得的小文件名分别建立输入流来合并成一个大文件,并拷贝到sdcard中。

 1 public static void main(String[] args) throws IOException { 
2 //需要分割的文件放置的路径
3 String path = "E:/";
4 //需要分割的文件的文件名称
5 String base = "demo";
6 //需要分割的文件的后缀名
7 String ext = ".db";
8 //以每个小文件1024*1024字节即1M的标准来分割
9 int split = 1024 * 1024;
10 byte[] buf = new byte[1024];
11 int num = 1;
12 //建立输入流
13 File inFile = new File(path + base + ext);
14 FileInputStream fis = new FileInputStream(inFile);
15 while (true) {
16 //以"demo"+num+".db"方式来命名小文件即分割后为demo1.db,demo2.db,。。。。。。
17 FileOutputStream fos = new FileOutputStream(new File(path + base
18 + num + ext));
19 for (int i = 0; i < split / buf.length; i++) {
20 int read = fis.read(buf);
21 fos.write(buf, 0, read);
22 // 判断大文件读取是否结束
23 if (read < buf.length) {
24 fis.close();
25 fos.close();
26 return;
27 }
28 }
29 fos.close();
30 num++;
31 }
32 }

获取输入流来合并文件,我们这里以assets文件夹下的文件为例

AssetManager assetManager = getAssets();
String[] data = assetManager.list("");
mergeFile(this, data, pathinfo);   
 1 package com.kevin.aesfile;
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.app.Activity;
10 import android.content.Context;
11 import android.content.res.AssetManager;
12 import android.os.Bundle;
13 import android.os.Environment;
14
15 public class LogoActivity extends Activity {
16 private String folderPath = Environment.getExternalStorageDirectory() + "/kevin/dict/";
17 //private String folderName = "";// 文件夹的名字
18 private String fileName = "demo.db"; // 文件名
19
20 /** Called when the activity is first created. */
21 @Override
22 public void onCreate(Bundle savedInstanceState) {
23 super.onCreate(savedInstanceState);
24
25
26 String Pathinfo = folderPath+fileName;
27
28 //---------------以下两个成员变量是针对在SD卡中存储数据库文件使用
29 // private File path = new File("/sdcard/himi");// 创建目录
30 // private File f = new File("/sdcard/himi/himi.db");// 创建文件
31
32 //备注1 ----如果你使用的是将数据库的文件创建在SD卡中,那么创建数据库mysql如下操作:
33 if (!new File(folderPath).exists()) {// 目录存在返回false
34 File file = new File(folderPath);
35 file.mkdirs();// 创建一个目录 //
36 }
37
38 // 开始合并文件
39 AssetManager assetManager = getAssets();
40 String[] data = null;
41 try {
42 data = assetManager.list("");
43 } catch (IOException e) {
44 // TODO Auto-generated catch block
45 e.printStackTrace();
46 }
47 try {
48 mergeFile(this, data, Pathinfo);
49 } catch (IOException e) {
50 // TODO Auto-generated catch block
51 e.printStackTrace();
52 }
53
54 setContentView(R.layout.main);
55 System.out
56 .println("---------------------程序运行完毕!---------------------------");
57
58
59 }
60
61 // 合并文件方法
62 public static void mergeFile(Context c, String[] partFileList,String pathinfo) throws IOException {
63
64 if (!new File(pathinfo).exists()) {
65 System.out.println("----------------开始合并文件!---------------");
66 OutputStream out = new FileOutputStream(pathinfo);
67 byte[] buffer = new byte[1024];
68 InputStream in;
69 int readLen = 0;
70 for (int i = 0; i < partFileList.length; i++) {
71 // 获得输入流 ,注意文件的路径
72 in = c.getAssets().open(partFileList[i]);
73 while ((readLen = in.read(buffer)) != -1) {
74 out.write(buffer, 0, readLen);
75
76 }
77 out.flush();
78 in.close();
79 System.out
80 .println(" --------------第" + i + "次合并!-------------");
81 }
82 // 把所有小文件都进行写操作后才关闭输出流,这样就会合并为一个文件了
83 out.close();
84 System.out
85 .println("-------------------文件合并完成!--------------------");
86 } else {
87 System.out
88 .println("-------------------文件已经存在!--------------------");
89 }
90
91 }
92
93 }


 

 

文章来自:http://www.cnblogs.com/thinkfeed/archive/2011/10/27/2226922.html

 

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

导航