Android檔案儲存體使用參考

來源:互聯網
上載者:User

標籤:

可能遇到的問題

android系統自身內建有儲存,另外也可以通過sd卡來擴充儲存空間。前者好比pc中的硬碟,後者好移動硬碟。 前者空間較小,後者空間大,但後者不一定可用。 開發應用,處理本機資料存取時,可能會遇到這些問題:

  1. 需要判斷sd卡是否可用: 佔用過多機身內部儲存,容易招致使用者反感,優先將資料存放於sd卡;
  2. 應用資料存放路徑,同其他應用應該保持一致,應用卸載時,清除資料:

    • 標新立異在sd卡根目錄建一個目錄,招致使用者反感
    • 使用者卸載應用後,殘留目錄或者資料在使用者機器上,招致使用者反感
  3. 資料安全性,本應用資料不願意被其他應用讀寫;

  4. 圖片緩衝等,不應該被掃描加入到使用者相簿等媒體庫中去。

基本操作
  1. 使用外部儲存,需要的許可權,在AndoridManifest.xml中:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    從API 19 / Andorid 4.4 / KITKAT開始,不再需要顯式聲明這兩個許可權,除非要讀寫其他應用的應用資料($appDataDir)

  2. 判斷sd卡可用:

    /** * Check if the primary "external" storage device is available. *  * @return */public static boolean hasSDCardMounted() {    String state = Environment.getExternalStorageState();    if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {        return true;    } else {        return false;    }}
儲存的用量情況
  • 根據系統使用者不同,所能佔用的儲存空間大小也有不同

    在API level 9及其以上時,File對象的getFreeSpace()方法擷取系統root使用者可用空間;

    getUsableSpace()取非root使用者可用空間

  • 當有多個儲存可用時擷取磁碟用量,根據當前系統情況選用合適的儲存。

  • 根據系統儲存用量,合理設定app所用的空間大小;運行時,也可做動態調整。

  • 在API level 9及其以上的系統,可直接調用File對象的相關方法,以下需自行計算:

    @TargetApi(VERSION_CODES.GINGERBREAD)public static long getUsableSpace(File path) {    if (path == null) {        return -1;    }    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {        return path.getUsableSpace();    } else {        if (!path.exists()) {            return 0;        } else {            final StatFs stats = new StatFs(path.getPath());            return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks();        }    }}
路徑的規律

一般地,通過Context 和 Environment相關的方法擷取檔案存取的路徑。

通過這兩個類可擷取各種路徑,

    ($rootDir)+- /data                -> Environment.getDataDirectory()|   ||   |   ($appDataDir)|   +- data/com.srain.cube.sample|       ||       |   ($filesDir)|       +- files            -> Context.getFilesDir() / Context.getFileStreamPath("")|       |       ||       |       +- file1    -> Context.getFileStreamPath("file1")|       |   ($cacheDir)|       +- cache            -> Context.getCacheDir()|       ||       +- app_$name        ->(Context.getDir(String name, int mode)||   ($rootDir)+- /storage/sdcard0     -> Environment.getExternalStorageDirectory()    |                       / Environment.getExternalStoragePublicDirectory("")    |    +- dir1             -> Environment.getExternalStoragePublicDirectory("dir1")    |    |   ($appDataDir)    +- Andorid/data/com.srain.cube.sample        |        |   ($filesDir)        +- files        -> Context.getExternalFilesDir("")        |   |        |   +- file1    -> Context.getExternalFilesDir("file1")        |   +- Music    -> Context.getExternalFilesDir(Environment.Music);        |   +- Picture  -> ... Environment.Picture        |   +- ...        |        |   ($cacheDir)        +- cache        -> Context.getExternalCacheDir()        |        +- ???
各個路徑的特性

下面介紹這些路徑的特性以及使用中需要注意的細節:

  1. 根目錄($rootDir):

    • 內部儲存路徑: /data, 通過Environment.getDataDirectory() 擷取
    • 外部儲存路徑: /storage/sdcard0 (也有類似 /mnt/ 這樣的),通過Environment.getExternalStorageDirectory()擷取

      樣本:

      Environment.getDataDirectory():         /dataEnvironment.getExternalStorageDirectory():         /storage/sdcard0
  2. 應用資料目錄($appDataDir)

    • 內部儲存: $appDataDir = $rootDir/data/$packageName,
    • 外部儲存: $appDataDir = $rootDir/Andorid/data/$packageName

    在這些目錄下的資料,在app卸載之後,會被系統刪除,我們應將應用的資料放於這兩個目錄中。

  3. 外部儲存中,公開的資料目錄。 這些目錄將不會隨著應用的刪除而被系統刪除,請斟酌使用:

    Environment.getExternalStorageDirectory():     /storage/sdcard0// 同 $rootDirEnvironment.getExternalStoragePublicDirectory(""):     /storage/sdcard0Environment.getExternalStoragePublicDirectory("folder1"):     /storage/sdcard0/folder1
  4. 應用資料目錄下的目錄

    一般的在$appDataDir下,會有兩個目錄:

    1. 資料緩衝:$cacheDir = $appDataDir/cache:

      • 內部儲存:Context.getCacheDir(), 機身記憶體不足時,檔案會被刪除
      • 外部儲存:Context.getExternalCacheDir()

        外部儲存沒有即時監控,當空間不足時,檔案不會即時被刪除,可能返回Null 物件

        樣本:

        Context.getCacheDir():         /data/data/com.srain.cube.sample/cacheContext.getExternalCacheDir():         /storage/sdcard0/Android/data/com.srain.cube.sample/cache
    2. 檔案目錄 $filesDir = $appDataDir/files:

      • 內部儲存:通過Context.getFilesDir() 擷取

        Context.getFileStreamPath(String name)返回以name為檔案名稱的檔案對象,name為空白,則返回 $filesDir 本身

        樣本:

        Context.getFilesDir():         /data/data/com.srain.cube.sample/filesContext.getFileStreamPath(""):        /data/data/com.srain.cube.sample/filesContext.getFileStreamPath("file1"):        /data/data/com.srain.cube.sample/files/file1
      • 外部儲存:通過Context.getExternalFilesDir(String type), type為空白字串時擷取.

        type系統指定了幾種類型:

        Environment.DIRECTORY_MUSICEnvironment.DIRECTORY_PICTURES...

        樣本:

        Context.getExternalFilesDir(""):         /storage/sdcard0/Android/data/com.srain.cube.sample/filesContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC)        /storage/sdcard0/Android/data/com.srain.cube.sample/files/Music
    3. $cacheDir / $filesDir 安全性

      在內部儲存中,$cacheDir, $filesDir是app安全的,其他應用無法讀取本應用的資料,而外部儲存則不是。

      在外部儲存中,這兩個檔案夾其他應用程式也可訪問。

      在外部儲存中,$filesDir中的媒體檔案,不會被當做媒體掃描出來,加到媒體庫中。

    4. $cacheDir / $filesDir 同級目錄

      在內部儲存中:通過 Context.getDir(String name, int mode)可擷取和 $filesDir / $cacheDir 同級的目錄

      目錄的命名規則為 app_ + name, 通過mode可控制此目錄為app私人還是其他app可讀寫。

      樣本:

      Context.getDir("dir1", MODE_PRIVATE):        Context.getDir: /data/data/com.srain.cube.sample/app_dir1
    5. 特別注意, 對於外部儲存,擷取$cacheDir 或者 $filesDir及其下的路徑

      在API level 8 以下,或者空間不足,相關的方法獲路徑為空白時,需要自己構造。

      @TargetApi(VERSION_CODES.FROYO)public static File getExternalCacheDir(Context context) {    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)) {        File path = context.getExternalCacheDir();        // In some case, even the sd card is mounted,        // getExternalCacheDir will return null        // may be it is nearly full.        if (path != null) {            return path;        }    }    // Before Froyo or the path is null,    // we need to construct the external cache folder ourselves    final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";    return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);}



      相關代碼:

      https://github.com/liaohuqiu/cube-sdk/blob/master/core/src/in/srain/cube/diskcache/FileUtils.java

       

Android檔案儲存體使用參考

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.