Android存储小结-阿里云开发者社区

开发者社区> wei-spring> 正文

Android存储小结

简介: 转自:http://www.liaohuqiu.net/cn/posts/storage-in-android/ android系统自身自带有存储,另外也可以通过sd卡来扩充存储空间。前者好比pc中的硬盘,后者好移动硬盘。
+关注继续查看

 

转自:http://www.liaohuqiu.net/cn/posts/storage-in-android/

android系统自身自带有存储,另外也可以通过sd卡来扩充存储空间。前者好比pc中的硬盘,后者好移动硬盘。 前者空间较小,后者空间大,但后者不一定可用。 开发应用,处理本地数据存取时,可能会遇到这些问题:

  1. 需要判断sd卡是否可用: 占用过多机身内部存储,容易招致用户反感,优先将数据存放于sd卡;
  2. 应用数据存放路径,同其他应用应该保持一致,应用卸载时,清除数据:

    • 标新立异在sd卡根目录建一个目录,招致用户反感
    • 用户卸载应用后,残留目录或者数据在用户机器上,招致用户反感
  3. 需要判断两者的可用空间: sd卡存在时,可用空间反而小于机身内部存储,这时应该选用机身存储;

  4. 数据安全性,本应用数据不愿意被其他应用读写;

  5. 图片缓存等,不应该被扫描加入到用户相册等媒体库中去。

 

  1. 从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;
        }
    }
    

存储的用量情况

  • 根据系统用户不同,所能占用的存储空间大小也有不同

  •  


基本操作

  1. 使用外部存储,需要的权限,在AndoridManifest.xml中:

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

    • 在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(): 
                    /data
            
            Environment.getExternalStorageDirectory(): 
                    /storage/sdcard0
            

        1. 应用数据目录($appDataDir)

          • 内部储存: $appDataDir = $rootDir/data/$packageName,
          • 外部存储: $appDataDir = $rootDir/Andorid/data/$packageName

          在这些目录下的数据,在app卸载之后,会被系统删除,我们应将应用的数据放于这两个目录中。


        2. 外部存储中,公开的数据目录。 这些目录将不会随着应用的删除而被系统删除,请斟酌使用:

          Environment.getExternalStorageDirectory(): 
              /storage/sdcard0
          
          // 同 $rootDir
          Environment.getExternalStoragePublicDirectory(""): 
              /storage/sdcard0
          
          Environment.getExternalStoragePublicDirectory("folder1"): 
              /storage/sdcard0/folder1
          

          应用数据目录下的目录

          一般的在$appDataDir下,会有两个目录

          1. 数据缓存:$cacheDir = $appDataDir/cache:

            • 内部存储:Context.getCacheDir(), 机身内存不足时,文件会被删除
            • 外部存储:Context.getExternalCacheDir()

              外部存储没有实时监控,当空间不足时,文件不会实时被删除,可能返回空对象

              示例:

              Context.getCacheDir(): 
                      /data/data/com.srain.cube.sample/cache
              
              Context.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/files




          1. 相关代码:

            https://github.com/liaohuqiu/cube-sdk/blob/master/core/src/com/srain/cube/file/FileUtil.java

     

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
带你读《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW(二)
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW
14 0
带你读《存储漫谈Ceph原理与实践》第三章接入层3.1块存储 RBD
《存储漫谈Ceph原理与实践》第三章接入层3.1块存储 RBD
20 0
Android系统应用信息中存储和缓存的计算方法
进行如下操作: 设置->应用->选择一个应用->应用信息 会到达如下界面: 可以看到这个应用占用的磁盘空间。 先说结果,这几项会计算哪些文件(夹)。
770 0
Android OkHttp与物理存储介质缓存:DiskLruCache(2)
 Android OkHttp与物理存储介质缓存:DiskLruCache(2) 本文在附录文章8,9的基础之上,把Android OkHttp与DiskLruCache相结合,综合此两项技术,实现基于OkHttp的物理存储介质缓存DiskLruCache。
821 0
大话存储系列21——存储系统内部IO 上
1、IT系统的IO结构图 2、应用程序层IO 应用层程序是计算机系统内主动发起IO请求的大户,但是要知道,计算机内不止有应用程序可以向底层存储设备主动发起IO请求,其他的,比如文件系统自身、卷管理层自身、适配器驱动层自身等,都可以主动发起IO。
1008 0
Android二级缓存之物理存储介质上的缓存DiskLruCache
 Android二级缓存之物理存储介质上的缓存DiskLruCache Android DiskLruCache属于物理性质的缓存,相较于LruCache缓存,则DiskLruCache属于Android二级缓存中的最后一级。
705 0
+关注
wei-spring
Android 开发,Java 开发,Python开发
366
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载