淺談Android的文件存儲

由於項目須要,最近學了不少數據本地持久化的知識。有不少情景咱們都須要遇到文件存儲:從保存用戶的登陸狀態到記錄瀏覽信息,從保存圖片到下載大型文件。因此有必要了解下Android的文件存儲系統,從而輕鬆地去管理咱們應用日常產生的數據。java

內部存儲

這是按存儲的位置來分的。應用對內部存儲操做不須要任何的權限,這就意味着不須要在AndroidManifest.xml裏聲明權限,也不須要在Android6.0上進行權限適配。其實作過權限適配同窗都清楚,只有外部存儲的權限:Manifest.permission.READ_EXTERNAL_STORAGEManifest.permission.WRITE_EXTERNAL_STORAGE。我的理解:權限是爲了系統保證應用安全和用戶安全而設的,既然系統對內部存儲有着最高的管理權限,應用只能在系統分配的空間存儲文件,就不必有這個內部存儲權限了。android

咱們App在內部存儲都有本身的專有目錄: /data/data/PackageName。存放了 WebView 緩存頁面信息,SharedPreferences 和 數據庫數據等。不過沒root的是看不到的.固然咱們能夠經過Android Studio主界面右下處的Device File Exploer來查看:web

預建工做目錄

建立一個新應用,包名:com.renny.storage,系統在內部存儲默認建立了三個空文件夾,經過Context來獲取下:數據庫

  • File getFilesDir():返回內部存儲的Files文件夾
  • File getCacheDir():返回內部存儲的cache文件夾
  • File getCodeCacheDir() :返回內部存儲的code_cache文件夾,要求Android5.0+
  • File getDataDir() : 返回內部存儲的根文件夾,要求Android7.0+

一般咱們將文件存放在的Files文件夾,經過fileList()能夠獲取該文件夾下的所有文件的文件名。openFileInput()openFileOutput() 方法也是在該目錄下操做文件。這些方法都是Context裏的,在activity中能夠直接調用。舉個例子:緩存

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try{
            FileOutputStream outputStream = openFileOutput("hello.text", Context.MODE_PRIVATE);
            outputStream.write( "Hello world!".getBytes());
            outputStream.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
       String[] files = fileList();
        for (String file : files) {
            Log.d("file--",file);
        }
    }

複製代碼

這樣就會在Files文件夾下面生成一個hello.text文件了,打印出的信息就是 hello.text安全

其餘兩個是緩存文件夾,當內部存儲空間不足時,系統會自動優先刪除 cache和 code_cache文件夾裏的內容。code_cache文件夾在運行時存放應用產生的編譯或者優化的代碼,感受日常用不到。

其餘工做目錄

上面僅僅是一個全新應用預先建立的內部存儲目錄。其餘相關的子目錄以下(使用時建立):cookie

  • /data/data/PackageName/shared_prefs/ :
    用來存儲 SharedPreference,相關函數爲:getSharedPreferences(String fileName, int mode);app

  • /data/data/PackageName/databases/ide

    用來存儲數據庫文件,相關函數: getDatabasePath()函數

  • /data/data/PackageName/app_webview

  • /data/data/PackageName/xxxwebviewcachexxx 存儲應用內置 webview 所產生的 cache 和 cookies 等,該目錄因爲 android 版本不一樣名字和位置也可能不一樣;

  • /data/data/PackageName/lib

    用來存儲該應用的 .so 靜態庫文件;

小結

內部存儲空間較小,由於只對應用自己可見,適合保存一些私密信息,好比登陸信息,須要加密的數據等等,當一個應用卸載以後,內部存儲中的這些文件也會被刪除。另外內部存儲的文件讀取速度通常也是高於外部存儲的。

外部存儲

外部存儲空間就很是大了,你們買的手機32Gb,64Gb容量,還有還有XXGb的SD卡,都是外部存儲。外部存儲能夠直接在手機的文件管理應用中瀏覽。外部存儲中的文件是能夠被用戶或者其餘應用程序修改的(系統無論了),因此讀寫也須要Manifest.permission.READ_EXTERNAL_STORAGEManifest.permission.WRITE_EXTERNAL_STORAGE權限,來讓用戶本身管理。 有了權限,外部存儲的全部目錄咱們都能訪問到。 好比根目錄: Environment.getExternalStorageDirectory() 下面咱們按照存儲內容的用途來介紹:

公共文件目錄

Environment.getExternalStoragePublicDirectory(int type) 根據type會返回對應的文件目錄。這些文件目錄就是用來存放全部App均可能會用到的一些文件。type有不少種,好比: Environment.DIRECTORY_DCIM,獲得的就是外部存儲根文件夾下的DCIM文件夾,也就是手機存儲照片的地方。經常使用的還有:

  • Environment.DIRECTORY_DOWNLOADS Download文件夾
  • Environment.DIRECTORY_MUSIC Music文件夾
  • Environment.DIRECTORY_MOVIES Movies文件夾

等等等等。通常把須要和其餘應用共享的文件均可以放這裏(不過狀況好像不是不少)。

應用專屬文件目錄

雖然在外部存儲管不了應用在哪存取文件,但也不能任由應用胡亂在任何位置存文件,並且這些文件在應用卸載了之後也要刪除吧,否則到後來外部存儲全是卸載後應用留下的垃圾文件。因此Android有個目錄用來專門給應用存文件(固然想不想在那存,系統管不了)。目錄結構相似於內部存儲:

/storage/emulated/0/Android/data/PackageName/

方法也和內部存儲很相似:

  • Context.getExternalFilesDir(String type):Android/data/PackageName/files文件夾

  • Context.getExternalCacheDir():Android/data/PackageName/cache文件夾 上面的type和Environment.getExternalStoragePublicDirectory(int type)用法是相似的,有一點不一樣:

    能夠爲空:getContext().getExternalFilesDir(null):此時就是files根文件夾 Android/data/packageName/files

    也能夠傳一個值: getContext().getExternalFilesDir("apple"):此時就是files文件夾下的子文件夾:Android/data/packageName/files/apple

一些總結

  • 通常狀況下有包名的路徑咱們都是調用Context中的方法來得到,沒有包名的路徑,咱們直接調用Environment中的方法得到。
  • 使用外部存儲前要檢測權限和檢測狀態是否可用(一般對於sd卡來講),若是不能用就只能用內部存儲了:
state = Environment.getExternalStorageState();
if(state.equals(Environment.MEDIA_MOUNTED)){
    //todo
}
複製代碼
  • 關於設置->應用->應用詳情裏面的」清除數據「與」清除緩存「選項,前者會刪除全部的內部存儲和外部存儲的應用專屬文件目錄的文件夾;後者只會清楚內部存儲和外部存儲專屬文件目錄下的緩存文件夾。
相關文章
相關標籤/搜索