*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.raw.filename);
2.讀取assets下的檔案資源,通過以下方式擷取輸入流來進行寫操作
• AssetManager am = null;
• am = getAssets();
• InputStream is = am.open("filename");
在未知目錄下有哪些檔案,該去和擷取這些檔案的名稱并把檔案拷貝到目标目錄中呢?(用于内置檔案但不知道檔案名稱,需要篩選出想要的檔案然後拷貝到目标目錄中,推薦内置在assets檔案夾中)
1.res/raw目錄:
InputStream is = getResources().openRawResource(R.raw.filename);通過這個方法獲得raw中的檔案流,讀取大家應該都會。
2.assets目錄:
getAssets().list("");來擷取assets目錄下所有檔案夾和檔案的名稱,再通過這些名稱再讀取我們想要的檔案。
上次說到Android中資源檔案夾res/raw和assets的使用,但是在讀取這兩個資源檔案夾中的檔案時會有一定的限制,即單個檔案大小不能超過1M,如果讀取超過1M的檔案會報"Data exceeds UNCOMPRESS_DATA_MAX (1314625 vs 1048576)"的IOException。
解決方法如下(假設我們現在要把一個超過1M的檔案在程式啟動時拷貝到sdcard中)
1.先把需要拷貝的大檔案分割成若幹個大小小于1M的小檔案(事先寫個程式來分隔或者使用一些工具,我這裡直接寫了個程式),把這些小檔案放在assets檔案夾中;2.在程式啟動時我們擷取這些小檔案的檔案名,當然我們得事先規定小檔案的命名方式友善我們來擷取這些檔案名;
3.通過獲得的小檔案名分别建立輸入流來合并成一個大檔案,并拷貝到sdcard中。
下面是解決方法中需要用到的一些代碼,僅供參考,不妨自己寫。分割大檔案的方法:
1.
2. public static void main(String[] args) throws Exception {
3. // 大檔案放置的路徑
4. String path = "D:/";
5. // 大檔案的檔案名稱
6. String base = "demo";
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檔案夾下的檔案為例,raw檔案夾下如何擷取輸入流請參考之前的那篇博文。
1.
2. private void mergeApkFile(Context c, ArrayList<String> partFileList, String dst) throws IOException {
3. if (!new File(dst).exists()) {
4. OutputStream out = new FileOutputStream(dst);
5. byte[] buffer = new byte[1024];
6. InputStream in;
7. int readLen = 0;
8. for(int i=0;i<partFileList.size();i++){
9. // 獲得輸入流
10. in = c.getAssets().open(partFileList.get(i));
11. while((readLen = in.read(buffer)) != -1){
12. out.write(buffer, 0, readLen);
13. }
14. out.flush();
15. in.close();
16. }
17. // 把所有小檔案都進行寫操作後才關閉輸出流,這樣就會合并為一個檔案了
18. out.close();
19. }
20. }