1. 程式人生 > >Android 檔案儲存策略

Android 檔案儲存策略

Android的檔案儲存有兩種型別: 內部儲存 和 外部儲存 。

首先來確定下一些易混淆的概念:

  1. 內部儲存 不是記憶體,內部儲存位於系統中很特殊的一個位置。

  2. 外部儲存 不一定是 SD 卡, 機身儲存也是外部儲存。比如 16GB 版本的安卓手機,機子本身就帶了外部儲存。對於開發來說,最關鍵的是,我們都是通過相同的 api 來訪問可移動的 sdcard 或者手機自帶的儲存(外部儲存)。

  3. 絕對路徑是檔案的 完整路徑,例如d:\java\Hello.java,該路徑中包含檔案的完整路徑d:\java以及檔案的全名Hello.java。使用該路徑可以唯一的找到一個檔案,不會產生歧義。但是使用絕對路徑在表示檔案時,受到的限制很大,且不能在不同的作業系統下執行,因為不同作業系統下絕對路徑的表達形式存在不同。

  4. 相對路徑是檔案的 部分路徑,例如\test\Hello.java,該路徑中只包含檔案的部分路徑\test和檔案的全名Hello.java,部分路徑是指當前路徑下的子路徑,例如當前程式在d:\abc下執行,則該檔案的完整路徑就是d:\abc\test。使用這種形式,可以更加通用的代表檔案的位置,使得檔案路徑產生一定的靈活性。

內部儲存

內部儲存是指將應用程式中的資料以檔案方式儲存到裝置的內部儲存空間中(該檔案位於 data/data/your_package_name/ 目錄下)。

如果想把檔案儲存在內部儲存中,那麼檔案 預設只能被當前應用訪問,且一個應用所建立的所有檔案都在和應用包名相同的目錄下。也就是說應用創建於內部儲存的檔案,與這個應用是關聯起來的。當一個應用解除安裝之後,內部儲存中的這些檔案也被刪除。理論上來講,如果應用建立的檔案設定為可讀,那麼其他 app 在知道你應用包名的情況下,也是可以訪問這些檔案的。

需要注意的是,內部儲存資源十分珍貴,它也是系統本身和系統應用程式主要的資料儲存所在地,一旦內部儲存空間耗盡,手機也就無法使用了。所以對於內部儲存空間,我們要儘量避免使用。Shared Preferences 和 SQLite 資料庫都是儲存在內部儲存空間上的。內部儲存一般用 Context 來獲取和操作。

外部儲存

don’t be confused by the word “external” here. This directory can
better be thought as media/shared storage. It is a filesystem that can
hold a relatively large amount of data and that is shared across all
applications (does not enforce permissions). Traditionally this is an
SD card, but it may also be implemented as built-in storage in a
device that is distinct from the protected internal storage and can be
mounted as a filesystem on a computer.
關於外部儲存,在 api 中 Environment.getExternalStorageDirectory() 方法說得很清楚:

外部儲存可認為是一個擁有超大容量媒體儲存庫(敲重點:相簿、音訊處理相關的程式生成的檔案都要放在這裡啊),而且外部儲存的表現形式不僅是 sd 卡,還有內建在手機的儲存空間。所以不管是 sd 卡還是手機自身內建的儲存空間,都是呼叫相同的 api。

內部儲存的儲存策略

內部儲存根據檔案型別大概可以可以分為三種:

  1. 自定義(其路徑為/data/data/Your Package Name/app_”your_defined_name”,檔名字系統預設會新增一個字首“app_”)

  2. Files(其路徑為/data//data/Your Package Name/files), api 中提供了比較多的方法來操作該目錄下的檔案。

  3. cache快取(其路徑為/data/data/Your Package Name/cache)是快取檔案的存放地址。

這三種一般的呼叫方式如下:

        /* 
         * 1.建立並返回一個指定名稱的目錄,在這個目錄下來存些東西 輸出結果為: 
         *   getDir():/data/data/com.example.filedemo/app_abc 
         */  
        File dir1 = getDir("abc", MODE_PRIVATE);  
        Log.i("MainActivity", "getDir():" + dir1.toString());  

        /* 
         * 2.建立並返回一個目錄,在這個目錄下儲存應用程式的資料檔案 輸出結果為: 
         *   getFilesDir():/data/data/com.example.filedemo/files 
         */  
        File dir2 = getFilesDir();  
        Log.i("MainActivity", "getFilesDir():" + dir2.toString());  

        /* 
         * 3.開啟一個輸出流物件,通過這個輸出流物件可以向abc.txt檔案中寫入一些資料, 
         * abc.txt檔案位於/data/data/com.example.filedemo/files下; 
         */  
        try {  
            FileOutputStream out = openFileOutput("abc.txt", MODE_PRIVATE);  
            out.write("hello world".getBytes());  
            out.flush();  
            out.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  

        /* 
         * 4.獲取一個輸入流物件,通過這個輸入流對物件讀取指定檔案,這個檔案在/data/data/com.example.filedemo/files下; 
         */  
        try {  
            FileInputStream is = openFileInput("abc.txt");  
            ByteArrayOutputStream out = new ByteArrayOutputStream();  
            int len = 0;  
            byte[] buf = new byte[4];  
            while ((len = is.read(buf)) > 0) {  
                out.write(buf, 0, len);  
                out.flush();  
            }  
            out.close();  
            is.close();  
            Log.i("MainActivity", "openFileInput()讀取到的資料:"+out.toString());  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
 /* 
         * 5.建立並返回一個目錄,在這個目錄下儲存應用程式的緩衝檔案,當系統資源不足時,系統清除這下面的檔案 
         * 輸出結果為:getCacheDir():/data/data/com.example.filedemo/cache 
         */  
        File dir3 = getCacheDir();  
        Log.i("MainActivity", "getCacheDir():" + dir3.toString());  

有建立檔案就有刪除檔案

 /* 
         * 6.刪除 /data/data/com.example.filedemo/files資料夾下面某個檔案。 
         * 重新執行一下第3條的程式碼,換個檔名,測試deleteFile()函式。 
         */  
        try {  
            FileOutputStream out = openFileOutput("abc2.txt", MODE_PRIVATE);  
            out.write("hello world".getBytes());  
            out.flush();  
            out.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        // 刪除剛才建立的檔案  
        deleteFile("abc2.txt"); 

內部儲存大概是這麼些個套路。

外部儲存的儲存策略

外部儲存主要有兩種型別:

  1. 公共檔案。檔案是可以被自由訪問,且檔案的資料對其他應用或者使用者來說都是有意義的,當應用被解除安裝之後,其解除安裝前建立的檔案仍然保留。比如camera應用,生成的照片大家都能訪問,而且camera不在了,照片仍然在。
    getExternalStoragePublicDirectory()方法接受一個字串常量,即前面寫到的Environment的那些靜態常量,來確定想要訪問的子目錄。注意,如果返回的目錄不存在,必須在向該目錄寫入檔案前先建立它。

  2. 私有檔案。由於是外部儲存的原因,即使是私有型別的檔案也能被其他程式訪問,只不過一個應用私有的檔案對其他應用其實是沒有訪問價值的(惡意程式除外)。外部儲存上,應用私有檔案的價值在於解除安裝之後,這些檔案也會被刪除,類似於內部儲存。所有應用程式的外部儲存的私有檔案都放在根目錄的Android/data/下,目錄形式為/Android/data//

        /* 
         * 9.建立並返回外部儲存檔案目錄,需要sd卡的的寫入資料許可權; 
         * 輸出結果是:getExternalFilesDir():/mnt/sdcard/Android/data/com.example.filedemo/files/Music 
         */  
        if (status.equals(Environment.MEDIA_MOUNTED)) {  
            File dir4 = getExternalFilesDir(Environment.DIRECTORY_MUSIC);  
            Log.i("MainActivity", "getExternalFilesDir():" + dir4.toString());  
        }   


        /* 
         * 10.建立並返回外部儲存檔案目錄,需要sd卡的的寫入資料許可權; 
         * 輸出結果是:getExternalFilesDir():/mnt/sdcard/Android/data/com.example.filedemo/files/albumName
         */ 
        File file   = newFile(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES), albumName);
        if(!file.mkdirs()) {
            Log.e(LOG_TAG, "Directory not created");
}
    Log.i("MainActivity","getExternalStoragePublicDirectory():"+file.toString());

        /* 
         * 11.建立並返回外部儲存緩衝目錄,需要sd卡的寫入資料許可權; 
         * 輸出結果是:getExternalCacheDir():/mnt/sdcard/Android/data/com.example.filedemo/cache 
         */  
        if (status.equals(Environment.MEDIA_MOUNTED)) {  
            File dir5 = getExternalCacheDir();  
            Log.i("MainActivity", "getExternalCacheDir():" + dir5.toString());  
        }   

檔案的多級儲存

多級儲存需要逐級建立資料夾,再強調一下,真的需要一級一級地建立,如果直接指向目標多級資料夾的地址,前序資料夾又沒有建立,那麼這個地址就訪問不了。

          //資料夾目錄"/sdcard/FirstFolder/SecondFolder",多級目錄必須逐一建立  

             public static String FirstFolder="FirstFolder";//一級目錄  

             public static String SecondFolder="SecondFolder";//二級目錄  

             /*ALBUM_PATH取得機器的SD卡位置,File.separator為分隔符“/”*/  

             private final static String ALBUM_PATH=Environment.getExternalStorageDirectory()+File.separator+FirstFolder+File.separator;  

             private final static String Second_PATH=ALBUM_PATH+SecondFolder+File.separator;  

建立過程

//檢查手機上是否有外部儲存卡  

             boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);  

             if(!sdCardExist)  

             {//如果不存在SD卡,進行提示  

                  Toast.makeText(YuanTuActivity.this, "請插入外部SD儲存卡", Toast.LENGTH_SHORT).show();  

             }else{//如果存在SD卡,判斷資料夾目錄是否存在  

                 //一級目錄和二級目錄必須分開建立  

                 File dirFirstFile=new File(ALBUM_PATH);//新建一級主目錄  

                 if(!dirFirstFile.exists()){//判斷資料夾目錄是否存在  

                      dirFirstFile.mkdir();//如果不存在則建立  

                 }  

                 File dirSecondFile=new File(Second_PATH);//新建二級主目錄  

                 if(!dirSecondFile.exists()){//判斷資料夾目錄是否存在  

                      dirSecondFile.mkdir();//如果不存在則建立  

                 }  

             } 

相關推薦

Android 檔案儲存策略

Android的檔案儲存有兩種型別: 內部儲存 和 外部儲存 。 首先來確定下一些易混淆的概念: 內部儲存 不是記憶體,內部儲存位於系統中很特殊的一個位置。 外部儲存 不一定是 SD 卡, 機身儲存也是外部儲存。比如 16GB 版本的安卓手機,機子本身就帶

Android檔案儲存路徑分析

1.internal or external storage 內部儲存和外部儲存的對比: 1.內部儲存永遠可以訪問,由於外部儲存可能是SD卡,可能無法訪問; 2.內部儲存檔案只有本App才能訪問,外部儲存檔案可以共享給其他APP; 3.解除安裝APP,相應的內部儲存檔案被系統刪除

Android檔案儲存目錄

儲存路徑包含包名的:使用context獲取; 儲存路徑不包含包名的:使用Environment獲取; /** * 顯示儲存空間路徑 * <br/> */ private static void showStorageU

iOS 5的檔案儲存策略應對

蘋果在iOS 5系統時,對app的檔案儲存提出了新的要求。從它的guildline來看,是推薦開發者儘量把app生成的檔案放在Caches目錄下的。原文如下: Only user-generated data or that cannot otherwise be r

[ios2] iOS 5的檔案儲存策略應對【轉】

蘋果在iOS 5系統時,對app的檔案儲存提出了新的要求。從它的guildline來看,是推薦開發者儘量把app生成的檔案放在Caches目錄下的。原文如下: Only user-generated data or that cannot otherwise be recr

Android檔案儲存的問題:ClassLoader和實現Parcelable介面後 詳解及用途

可能小夥伴們讀了我上一篇部落格關於Android檔案儲存的的,在檔案操作的時候大家有沒有疑問呀,有就對了,可能在儲存自定義物件的時候,如何序列化呀?ClassLoader到底是啥鬼呀?序列化後怎麼讀取出來呀?好吧,針對於上面的問題,我一個一個的說明吧! 今天主

Android 檔案儲存淺析

最近做的一個需求和檔案儲存有關係。由於之前沒有系統梳理過,對檔案儲存方面的知識一直很懵懂。趁著週末有時間,趕緊梳理一波。 這首從網上找到的一張圖,很好的概括了外部儲存和內部儲存。   下面我們再來具體介紹相關知識和內容。 內部儲存  內部儲存,位於data/data/包名/路徑下

android 資料儲存&lt;一&gt;----android簡訊傳送器之檔案的讀寫(手機+SD卡)

本文實踐知識點有有三: 1.佈局檔案,android佈局有相對佈局。線性佈局,絕對佈局。表格佈局。標籤佈局等,各個佈局能夠巢狀的。 本文的佈局檔案就是線性佈局的巢狀 <LinearLayout xmlns:android="http://schemas.and

android開發的檔案儲存地址選擇

作為一個開發者,我們經常需要通過快取一些檔案到SD卡中,常見的方式就是,通過: File sdCard = Environment.getExternalStorageDirectory(); 獲取SD卡根目錄,然後自定義檔案/檔名進行檔案儲存.這樣做法的結果就是,當手機安裝了大量的a

Android入門 File檔案儲存

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

android刪除儲存卡中的目錄及目錄下的檔案

首先,需要在AndroidManifest.xml中配置寫許可權 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 刪除檔案方法 public static boolean

Android五種資料儲存方式之檔案儲存 內部儲存 外部儲存 檔案讀取儲存操作封裝

檔案儲存 前言 檔案儲存 記憶體 內部儲存 外部儲存 內部儲存操作 API 讀寫操作 外部儲存操作 公共目錄 私有目錄

Android複習之旅--檔案儲存

內部儲存 內部儲存是指將應用程式中的資料以檔案方式儲存到裝置的內部儲存空間中(該檔案位於 data/data// 目錄下)。 一般情況下應用儲存在記憶體下的資料其他應用是訪問不了的,當您希望確保使用者或其他應用均無法訪問您的檔案時,內部儲存是最佳選擇。使用者解除安裝

Android 手機儲存檔案各種路徑

String cacheDir = context.getExternalCacheDir().getPath(); /storage/emulated/0/Android/data/應用名稱/cache 一般放一些長時間儲存的資料 String filesDir = context.ge

Android中的資料儲存一(檔案儲存、SharedPreferences儲存)

一.檔案儲存 檔案儲存不對儲存的內容進行處理,適合用於儲存一些簡單的文字資料或二進位制資料。如果要儲存較為複雜的文字資料,就要定義一套自己的格式規範。 1.將資料儲存到檔案中 Context類中有一個 openFileOutput(String name, int mo

Android火車票訂購軟體之註冊和檔案儲存(2)

上次我們做了app啟動時的延時頁,這次我們來做登陸註冊的頁面。 xml程式碼: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.c

android進階4step1:android小知識 檔案儲存

檔案儲存 作為一個開發者,我們經常需要通過快取一些檔案到 SD 卡中,常見的方式就是,通過: File sdCard = Environment.getExternalStorageDirectory(); 獲取 SD 卡根目錄,然後自定義檔案/檔名進行檔案儲存.這樣做法的結果就是,當手

Android檔案儲存-內部儲存

Table of Contents 檔案的操作模式 儲存資料  讀取資料   檔案的操作模式 MODE_PRIVATE:該檔案只能被當前程式讀寫 MODE_APPEND:該檔案的內容可以追加 MODE_WORLD_READABLE:可

Android重溫--檔案儲存

今天回憶一下Android五種儲存方式之”檔案儲存“。上次的部落格中我們回憶了-SharedPreferencesd的儲存和讀取。因為其是一種輕量級的儲存方式,只能儲存基本資料型別,無法儲存圖片等資料。所以我們回想一下“檔案儲存”,看看它可以實現哪些功能! 一

Android實現截圖,將截圖檔案儲存到本地資料夾

Android實現對當前介面截圖,並將截圖檔案存放至本地資料夾 首先需要動態申請兩項許可權(Android6.0後危險許可權之類的都需要動態申請),在AndroidManifest.xml中靜態新增 <uses-permission android:name="android.perm